aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2018-05-02 13:36:19 -0400
committerIngo Molnar <mingo@kernel.org>2018-05-02 13:36:19 -0400
commiteaeb1f4d892936133c5f8d3aafb36b7f384fe59c (patch)
tree6829eabc8ba773559d8a8b018c779664c978e58e
parent2d618bdf71635463a4aa4ad0fe46ec852292bc0c (diff)
parent107cad95ffd81afad295ed5c29d006e525f1f80f (diff)
Merge tag 'perf-core-for-mingo-4.18-20180502' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: perf stat: (Jiri Olsa) - Display time in precision based on std deviation - Add --table option to display time of each run - Display length strings of each run for --table option perf buildid-cache: (Ravi Bangoria) - Add --list and --purge-all options perf test: (Hendrik Brueckner) - Let 'perf test list' display subtests Core libraries: - Remove the splitting of maps into MAP__FUNCTION and MAP__VARIABLE. It isn't needed, adds complexity, so remove this split in a very granular fashion using better ways of detecting if a map is executable, using map->prot, etc. More is needed to further untangle map aspects from DSO ones and also to have arch specific stuff better isolated. (Arnaldo Carvalho de Melo) - Fix spelling mistake: "builid" -> "buildid" in a jitdump error message (Colin Ian King) Build system: (Jiri Olsa) - Add support to check 2 independent files in check-headers.sh Documentation: (Takashi Iwai) - Support for asciidoctor, since 'asciidoc' wasn't so far ported to python3 and distros are ditching python2 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/lib/symbol/kallsyms.c6
-rw-r--r--tools/lib/symbol/kallsyms.h2
-rw-r--r--tools/perf/Documentation/Makefile29
-rw-r--r--tools/perf/Documentation/asciidoctor-extensions.rb29
-rw-r--r--tools/perf/Documentation/perf-buildid-cache.txt7
-rw-r--r--tools/perf/Documentation/perf-stat.txt16
-rw-r--r--tools/perf/arch/arm/tests/dwarf-unwind.c2
-rw-r--r--tools/perf/arch/arm64/tests/dwarf-unwind.c2
-rw-r--r--tools/perf/arch/powerpc/tests/dwarf-unwind.c2
-rw-r--r--tools/perf/arch/powerpc/util/skip-callchain-idx.c3
-rw-r--r--tools/perf/arch/x86/tests/dwarf-unwind.c2
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-buildid-cache.c77
-rw-r--r--tools/perf/builtin-inject.c4
-rw-r--r--tools/perf/builtin-kallsyms.c2
-rw-r--r--tools/perf/builtin-kmem.c6
-rw-r--r--tools/perf/builtin-report.c14
-rw-r--r--tools/perf/builtin-script.c30
-rw-r--r--tools/perf/builtin-stat.c92
-rw-r--r--tools/perf/builtin-timechart.c8
-rw-r--r--tools/perf/builtin-top.c7
-rw-r--r--tools/perf/builtin-trace.c9
-rwxr-xr-xtools/perf/check-headers.sh30
-rw-r--r--tools/perf/tests/builtin-test.c9
-rw-r--r--tools/perf/tests/code-reading.c5
-rw-r--r--tools/perf/tests/hists_common.c6
-rw-r--r--tools/perf/tests/mmap-thread-lookup.c7
-rw-r--r--tools/perf/tests/vmlinux-kallsyms.c20
-rw-r--r--tools/perf/ui/browsers/map.c2
-rw-r--r--tools/perf/ui/stdio/hist.c3
-rw-r--r--tools/perf/util/auxtrace.c12
-rw-r--r--tools/perf/util/build-id.c4
-rw-r--r--tools/perf/util/cs-etm.c4
-rw-r--r--tools/perf/util/db-export.c7
-rw-r--r--tools/perf/util/dso.c34
-rw-r--r--tools/perf/util/dso.h37
-rw-r--r--tools/perf/util/event.c37
-rw-r--r--tools/perf/util/genelf.c2
-rw-r--r--tools/perf/util/intel-bts.c3
-rw-r--r--tools/perf/util/intel-pt.c8
-rw-r--r--tools/perf/util/machine.c162
-rw-r--r--tools/perf/util/machine.h47
-rw-r--r--tools/perf/util/map.c99
-rw-r--r--tools/perf/util/map.h59
-rw-r--r--tools/perf/util/probe-event.c29
-rw-r--r--tools/perf/util/session.c13
-rw-r--r--tools/perf/util/sort.c6
-rw-r--r--tools/perf/util/srcline.c1
-rw-r--r--tools/perf/util/stat.h3
-rw-r--r--tools/perf/util/symbol-elf.c275
-rw-r--r--tools/perf/util/symbol-minimal.c3
-rw-r--r--tools/perf/util/symbol.c205
-rw-r--r--tools/perf/util/symbol.h24
-rw-r--r--tools/perf/util/symbol_fprintf.c4
-rw-r--r--tools/perf/util/thread.c35
-rw-r--r--tools/perf/util/thread.h13
-rw-r--r--tools/perf/util/unwind-libdw.c23
-rw-r--r--tools/perf/util/unwind-libunwind-local.c19
-rw-r--r--tools/perf/util/vdso.c6
59 files changed, 794 insertions, 813 deletions
diff --git a/tools/lib/symbol/kallsyms.c b/tools/lib/symbol/kallsyms.c
index 689b6a130dd7..96d830545bbb 100644
--- a/tools/lib/symbol/kallsyms.c
+++ b/tools/lib/symbol/kallsyms.c
@@ -10,6 +10,12 @@ u8 kallsyms2elf_type(char type)
10 return (type == 't' || type == 'w') ? STT_FUNC : STT_OBJECT; 10 return (type == 't' || type == 'w') ? STT_FUNC : STT_OBJECT;
11} 11}
12 12
13bool kallsyms__is_function(char symbol_type)
14{
15 symbol_type = toupper(symbol_type);
16 return symbol_type == 'T' || symbol_type == 'W';
17}
18
13int kallsyms__parse(const char *filename, void *arg, 19int kallsyms__parse(const char *filename, void *arg,
14 int (*process_symbol)(void *arg, const char *name, 20 int (*process_symbol)(void *arg, const char *name,
15 char type, u64 start)) 21 char type, u64 start))
diff --git a/tools/lib/symbol/kallsyms.h b/tools/lib/symbol/kallsyms.h
index bc40101d72c1..72ab9870454b 100644
--- a/tools/lib/symbol/kallsyms.h
+++ b/tools/lib/symbol/kallsyms.h
@@ -20,6 +20,8 @@ static inline u8 kallsyms2elf_binding(char type)
20 20
21u8 kallsyms2elf_type(char type); 21u8 kallsyms2elf_type(char type);
22 22
23bool kallsyms__is_function(char symbol_type);
24
23int kallsyms__parse(const char *filename, void *arg, 25int kallsyms__parse(const char *filename, void *arg,
24 int (*process_symbol)(void *arg, const char *name, 26 int (*process_symbol)(void *arg, const char *name,
25 char type, u64 start)); 27 char type, u64 start));
diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile
index db11478e30b4..42261a9b280e 100644
--- a/tools/perf/Documentation/Makefile
+++ b/tools/perf/Documentation/Makefile
@@ -47,7 +47,8 @@ man5dir=$(mandir)/man5
47man7dir=$(mandir)/man7 47man7dir=$(mandir)/man7
48 48
49ASCIIDOC=asciidoc 49ASCIIDOC=asciidoc
50ASCIIDOC_EXTRA = --unsafe 50ASCIIDOC_EXTRA = --unsafe -f asciidoc.conf
51ASCIIDOC_HTML = xhtml11
51MANPAGE_XSL = manpage-normal.xsl 52MANPAGE_XSL = manpage-normal.xsl
52XMLTO_EXTRA = 53XMLTO_EXTRA =
53INSTALL?=install 54INSTALL?=install
@@ -55,6 +56,14 @@ RM ?= rm -f
55DOC_REF = origin/man 56DOC_REF = origin/man
56HTML_REF = origin/html 57HTML_REF = origin/html
57 58
59ifdef USE_ASCIIDOCTOR
60ASCIIDOC = asciidoctor
61ASCIIDOC_EXTRA = -a compat-mode
62ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions
63ASCIIDOC_EXTRA += -a mansource="perf" -a manmanual="perf Manual"
64ASCIIDOC_HTML = xhtml5
65endif
66
58infodir?=$(prefix)/share/info 67infodir?=$(prefix)/share/info
59MAKEINFO=makeinfo 68MAKEINFO=makeinfo
60INSTALL_INFO=install-info 69INSTALL_INFO=install-info
@@ -73,10 +82,12 @@ ifeq ($(_tmp_tool_path),)
73 missing_tools = $(ASCIIDOC) 82 missing_tools = $(ASCIIDOC)
74endif 83endif
75 84
85ifndef USE_ASCIIDOCTOR
76_tmp_tool_path := $(call get-executable,$(XMLTO)) 86_tmp_tool_path := $(call get-executable,$(XMLTO))
77ifeq ($(_tmp_tool_path),) 87ifeq ($(_tmp_tool_path),)
78 missing_tools += $(XMLTO) 88 missing_tools += $(XMLTO)
79endif 89endif
90endif
80 91
81# 92#
82# For asciidoc ... 93# For asciidoc ...
@@ -264,9 +275,17 @@ clean:
264 275
265$(MAN_HTML): $(OUTPUT)%.html : %.txt 276$(MAN_HTML): $(OUTPUT)%.html : %.txt
266 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ 277 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
267 $(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf \ 278 $(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage \
279 $(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) -o $@+ $< && \
280 mv $@+ $@
281
282ifdef USE_ASCIIDOCTOR
283$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.txt
284 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
285 $(ASCIIDOC) -b manpage -d manpage \
268 $(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) -o $@+ $< && \ 286 $(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) -o $@+ $< && \
269 mv $@+ $@ 287 mv $@+ $@
288endif
270 289
271$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml 290$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml
272 $(QUIET_XMLTO)$(RM) $@ && \ 291 $(QUIET_XMLTO)$(RM) $@ && \
@@ -274,7 +293,7 @@ $(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml
274 293
275$(OUTPUT)%.xml : %.txt 294$(OUTPUT)%.xml : %.txt
276 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ 295 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
277 $(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \ 296 $(ASCIIDOC) -b docbook -d manpage \
278 $(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) -o $@+ $< && \ 297 $(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) -o $@+ $< && \
279 mv $@+ $@ 298 mv $@+ $@
280 299
@@ -321,13 +340,13 @@ howto-index.txt: howto-index.sh $(wildcard howto/*.txt)
321 mv $@+ $@ 340 mv $@+ $@
322 341
323$(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt 342$(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt
324 $(QUIET_ASCIIDOC)$(ASCIIDOC) -b xhtml11 $*.txt 343 $(QUIET_ASCIIDOC)$(ASCIIDOC) -b $(ASCIIDOC_HTML) $*.txt
325 344
326WEBDOC_DEST = /pub/software/tools/perf/docs 345WEBDOC_DEST = /pub/software/tools/perf/docs
327 346
328$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt 347$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt
329 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ 348 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
330 sed -e '1,/^$$/d' $< | $(ASCIIDOC) -b xhtml11 - >$@+ && \ 349 sed -e '1,/^$$/d' $< | $(ASCIIDOC) -b $(ASCIIDOC_HTML) - >$@+ && \
331 mv $@+ $@ 350 mv $@+ $@
332 351
333# UNIMPLEMENTED 352# UNIMPLEMENTED
diff --git a/tools/perf/Documentation/asciidoctor-extensions.rb b/tools/perf/Documentation/asciidoctor-extensions.rb
new file mode 100644
index 000000000000..d148fe95c0c4
--- /dev/null
+++ b/tools/perf/Documentation/asciidoctor-extensions.rb
@@ -0,0 +1,29 @@
1require 'asciidoctor'
2require 'asciidoctor/extensions'
3
4module Perf
5 module Documentation
6 class LinkPerfProcessor < Asciidoctor::Extensions::InlineMacroProcessor
7 use_dsl
8
9 named :chrome
10
11 def process(parent, target, attrs)
12 if parent.document.basebackend? 'html'
13 %(<a href="#{target}.html">#{target}(#{attrs[1]})</a>\n)
14 elsif parent.document.basebackend? 'manpage'
15 "#{target}(#{attrs[1]})"
16 elsif parent.document.basebackend? 'docbook'
17 "<citerefentry>\n" \
18 "<refentrytitle>#{target}</refentrytitle>" \
19 "<manvolnum>#{attrs[1]}</manvolnum>\n" \
20 "</citerefentry>\n"
21 end
22 end
23 end
24 end
25end
26
27Asciidoctor::Extensions.register do
28 inline_macro Perf::Documentation::LinkPerfProcessor, :linkperf
29end
diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt
index 73c2650bd0db..f6de0952ff3c 100644
--- a/tools/perf/Documentation/perf-buildid-cache.txt
+++ b/tools/perf/Documentation/perf-buildid-cache.txt
@@ -48,6 +48,9 @@ OPTIONS
48--purge=:: 48--purge=::
49 Purge all cached binaries including older caches which have specified 49 Purge all cached binaries including older caches which have specified
50 path from the cache. 50 path from the cache.
51-P::
52--purge-all::
53 Purge all cached binaries. This will flush out entire cache.
51-M:: 54-M::
52--missing=:: 55--missing=::
53 List missing build ids in the cache for the specified file. 56 List missing build ids in the cache for the specified file.
@@ -59,7 +62,9 @@ OPTIONS
59 exactly same build-id, that is replaced by new one. It can be used 62 exactly same build-id, that is replaced by new one. It can be used
60 to update kallsyms and kernel dso to vmlinux in order to support 63 to update kallsyms and kernel dso to vmlinux in order to support
61 annotation. 64 annotation.
62 65-l::
66--list::
67 List all valid binaries from cache.
63-v:: 68-v::
64--verbose:: 69--verbose::
65 Be more verbose. 70 Be more verbose.
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index e6c3b4e555c2..3a822f308e6d 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -116,6 +116,22 @@ Do not aggregate counts across all monitored CPUs.
116print counts using a CSV-style output to make it easy to import directly into 116print counts using a CSV-style output to make it easy to import directly into
117spreadsheets. Columns are separated by the string specified in SEP. 117spreadsheets. Columns are separated by the string specified in SEP.
118 118
119--table:: Display time for each run (-r option), in a table format, e.g.:
120
121 $ perf stat --null -r 5 --table perf bench sched pipe
122
123 Performance counter stats for 'perf bench sched pipe' (5 runs):
124
125 # Table of individual measurements:
126 5.189 (-0.293) #
127 5.189 (-0.294) #
128 5.186 (-0.296) #
129 5.663 (+0.181) ##
130 6.186 (+0.703) ####
131
132 # Final result:
133 5.483 +- 0.198 seconds time elapsed ( +- 3.62% )
134
119-G name:: 135-G name::
120--cgroup name:: 136--cgroup name::
121monitor only in the container (cgroup) called "name". This option is available only 137monitor only in the container (cgroup) called "name". This option is available only
diff --git a/tools/perf/arch/arm/tests/dwarf-unwind.c b/tools/perf/arch/arm/tests/dwarf-unwind.c
index 8cb347760233..9a0242e74cfc 100644
--- a/tools/perf/arch/arm/tests/dwarf-unwind.c
+++ b/tools/perf/arch/arm/tests/dwarf-unwind.c
@@ -25,7 +25,7 @@ static int sample_ustack(struct perf_sample *sample,
25 25
26 sp = (unsigned long) regs[PERF_REG_ARM_SP]; 26 sp = (unsigned long) regs[PERF_REG_ARM_SP];
27 27
28 map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp); 28 map = map_groups__find(thread->mg, (u64)sp);
29 if (!map) { 29 if (!map) {
30 pr_debug("failed to get stack map\n"); 30 pr_debug("failed to get stack map\n");
31 free(buf); 31 free(buf);
diff --git a/tools/perf/arch/arm64/tests/dwarf-unwind.c b/tools/perf/arch/arm64/tests/dwarf-unwind.c
index e907f0f4c20c..5522ce384723 100644
--- a/tools/perf/arch/arm64/tests/dwarf-unwind.c
+++ b/tools/perf/arch/arm64/tests/dwarf-unwind.c
@@ -25,7 +25,7 @@ static int sample_ustack(struct perf_sample *sample,
25 25
26 sp = (unsigned long) regs[PERF_REG_ARM64_SP]; 26 sp = (unsigned long) regs[PERF_REG_ARM64_SP];
27 27
28 map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp); 28 map = map_groups__find(thread->mg, (u64)sp);
29 if (!map) { 29 if (!map) {
30 pr_debug("failed to get stack map\n"); 30 pr_debug("failed to get stack map\n");
31 free(buf); 31 free(buf);
diff --git a/tools/perf/arch/powerpc/tests/dwarf-unwind.c b/tools/perf/arch/powerpc/tests/dwarf-unwind.c
index 30cbbd6d5be0..5f39efef0856 100644
--- a/tools/perf/arch/powerpc/tests/dwarf-unwind.c
+++ b/tools/perf/arch/powerpc/tests/dwarf-unwind.c
@@ -26,7 +26,7 @@ static int sample_ustack(struct perf_sample *sample,
26 26
27 sp = (unsigned long) regs[PERF_REG_POWERPC_R1]; 27 sp = (unsigned long) regs[PERF_REG_POWERPC_R1];
28 28
29 map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp); 29 map = map_groups__find(thread->mg, (u64)sp);
30 if (!map) { 30 if (!map) {
31 pr_debug("failed to get stack map\n"); 31 pr_debug("failed to get stack map\n");
32 free(buf); 32 free(buf);
diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
index 0c370f81e002..3598b8b75d27 100644
--- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c
+++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
@@ -248,8 +248,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain)
248 248
249 ip = chain->ips[2]; 249 ip = chain->ips[2];
250 250
251 thread__find_addr_location(thread, PERF_RECORD_MISC_USER, 251 thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
252 MAP__FUNCTION, ip, &al);
253 252
254 if (al.map) 253 if (al.map)
255 dso = al.map->dso; 254 dso = al.map->dso;
diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c
index 95036c7a59e8..7879df34569a 100644
--- a/tools/perf/arch/x86/tests/dwarf-unwind.c
+++ b/tools/perf/arch/x86/tests/dwarf-unwind.c
@@ -26,7 +26,7 @@ static int sample_ustack(struct perf_sample *sample,
26 26
27 sp = (unsigned long) regs[PERF_REG_X86_SP]; 27 sp = (unsigned long) regs[PERF_REG_X86_SP];
28 28
29 map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp); 29 map = map_groups__find(thread->mg, (u64)sp);
30 if (!map) { 30 if (!map) {
31 pr_debug("failed to get stack map\n"); 31 pr_debug("failed to get stack map\n");
32 free(buf); 32 free(buf);
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 51709a961496..6e5d9f718154 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -228,7 +228,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
228 */ 228 */
229 if (al->sym != NULL) { 229 if (al->sym != NULL) {
230 rb_erase(&al->sym->rb_node, 230 rb_erase(&al->sym->rb_node,
231 &al->map->dso->symbols[al->map->type]); 231 &al->map->dso->symbols);
232 symbol__delete(al->sym); 232 symbol__delete(al->sym);
233 dso__reset_find_symbol_cache(al->map->dso); 233 dso__reset_find_symbol_cache(al->map->dso);
234 } 234 }
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index 41db2cba77eb..7a7403913b57 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -25,6 +25,7 @@
25#include "util/session.h" 25#include "util/session.h"
26#include "util/symbol.h" 26#include "util/symbol.h"
27#include "util/time-utils.h" 27#include "util/time-utils.h"
28#include "util/probe-file.h"
28 29
29static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid) 30static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid)
30{ 31{
@@ -239,6 +240,34 @@ out:
239 return err; 240 return err;
240} 241}
241 242
243static int build_id_cache__purge_all(void)
244{
245 struct strlist *list;
246 struct str_node *pos;
247 int err = 0;
248 char *buf;
249
250 list = build_id_cache__list_all(false);
251 if (!list) {
252 pr_debug("Failed to get buildids: -%d\n", errno);
253 return -EINVAL;
254 }
255
256 strlist__for_each_entry(pos, list) {
257 buf = build_id_cache__origname(pos->s);
258 err = build_id_cache__remove_s(pos->s);
259 pr_debug("Removing %s (%s): %s\n", buf, pos->s,
260 err ? "FAIL" : "Ok");
261 free(buf);
262 if (err)
263 break;
264 }
265 strlist__delete(list);
266
267 pr_debug("Purged all: %s\n", err ? "FAIL" : "Ok");
268 return err;
269}
270
242static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused) 271static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)
243{ 272{
244 char filename[PATH_MAX]; 273 char filename[PATH_MAX];
@@ -297,6 +326,26 @@ static int build_id_cache__update_file(const char *filename, struct nsinfo *nsi)
297 return err; 326 return err;
298} 327}
299 328
329static int build_id_cache__show_all(void)
330{
331 struct strlist *bidlist;
332 struct str_node *nd;
333 char *buf;
334
335 bidlist = build_id_cache__list_all(true);
336 if (!bidlist) {
337 pr_debug("Failed to get buildids: -%d\n", errno);
338 return -1;
339 }
340 strlist__for_each_entry(nd, bidlist) {
341 buf = build_id_cache__origname(nd->s);
342 fprintf(stdout, "%s %s\n", nd->s, buf);
343 free(buf);
344 }
345 strlist__delete(bidlist);
346 return 0;
347}
348
300int cmd_buildid_cache(int argc, const char **argv) 349int cmd_buildid_cache(int argc, const char **argv)
301{ 350{
302 struct strlist *list; 351 struct strlist *list;
@@ -304,6 +353,9 @@ int cmd_buildid_cache(int argc, const char **argv)
304 int ret = 0; 353 int ret = 0;
305 int ns_id = -1; 354 int ns_id = -1;
306 bool force = false; 355 bool force = false;
356 bool list_files = false;
357 bool opts_flag = false;
358 bool purge_all = false;
307 char const *add_name_list_str = NULL, 359 char const *add_name_list_str = NULL,
308 *remove_name_list_str = NULL, 360 *remove_name_list_str = NULL,
309 *purge_name_list_str = NULL, 361 *purge_name_list_str = NULL,
@@ -327,6 +379,8 @@ int cmd_buildid_cache(int argc, const char **argv)
327 "file(s) to remove"), 379 "file(s) to remove"),
328 OPT_STRING('p', "purge", &purge_name_list_str, "file list", 380 OPT_STRING('p', "purge", &purge_name_list_str, "file list",
329 "file(s) to remove (remove old caches too)"), 381 "file(s) to remove (remove old caches too)"),
382 OPT_BOOLEAN('P', "purge-all", &purge_all, "purge all cached files"),
383 OPT_BOOLEAN('l', "list", &list_files, "list all cached files"),
330 OPT_STRING('M', "missing", &missing_filename, "file", 384 OPT_STRING('M', "missing", &missing_filename, "file",
331 "to find missing build ids in the cache"), 385 "to find missing build ids in the cache"),
332 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), 386 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
@@ -344,11 +398,20 @@ int cmd_buildid_cache(int argc, const char **argv)
344 argc = parse_options(argc, argv, buildid_cache_options, 398 argc = parse_options(argc, argv, buildid_cache_options,
345 buildid_cache_usage, 0); 399 buildid_cache_usage, 0);
346 400
347 if (argc || (!add_name_list_str && !kcore_filename && 401 opts_flag = add_name_list_str || kcore_filename ||
348 !remove_name_list_str && !purge_name_list_str && 402 remove_name_list_str || purge_name_list_str ||
349 !missing_filename && !update_name_list_str)) 403 missing_filename || update_name_list_str ||
404 purge_all;
405
406 if (argc || !(list_files || opts_flag))
350 usage_with_options(buildid_cache_usage, buildid_cache_options); 407 usage_with_options(buildid_cache_usage, buildid_cache_options);
351 408
409 /* -l is exclusive. It can not be used with other options. */
410 if (list_files && opts_flag) {
411 usage_with_options_msg(buildid_cache_usage,
412 buildid_cache_options, "-l is exclusive.\n");
413 }
414
352 if (ns_id > 0) 415 if (ns_id > 0)
353 nsi = nsinfo__new(ns_id); 416 nsi = nsinfo__new(ns_id);
354 417
@@ -366,6 +429,11 @@ int cmd_buildid_cache(int argc, const char **argv)
366 429
367 setup_pager(); 430 setup_pager();
368 431
432 if (list_files) {
433 ret = build_id_cache__show_all();
434 goto out;
435 }
436
369 if (add_name_list_str) { 437 if (add_name_list_str) {
370 list = strlist__new(add_name_list_str, NULL); 438 list = strlist__new(add_name_list_str, NULL);
371 if (list) { 439 if (list) {
@@ -420,6 +488,9 @@ int cmd_buildid_cache(int argc, const char **argv)
420 } 488 }
421 } 489 }
422 490
491 if (purge_all)
492 ret = build_id_cache__purge_all();
493
423 if (missing_filename) 494 if (missing_filename)
424 ret = build_id_cache__fprintf_missing(session, stdout); 495 ret = build_id_cache__fprintf_missing(session, stdout);
425 496
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 40fe919bbcf3..a3b346359ba0 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -440,9 +440,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
440 goto repipe; 440 goto repipe;
441 } 441 }
442 442
443 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, &al); 443 if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) {
444
445 if (al.map != NULL) {
446 if (!al.map->dso->hit) { 444 if (!al.map->dso->hit) {
447 al.map->dso->hit = 1; 445 al.map->dso->hit = 1;
448 if (map__load(al.map) >= 0) { 446 if (map__load(al.map) >= 0) {
diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c
index bcfb363112d3..90d1a2305b72 100644
--- a/tools/perf/builtin-kallsyms.c
+++ b/tools/perf/builtin-kallsyms.c
@@ -27,7 +27,7 @@ static int __cmd_kallsyms(int argc, const char **argv)
27 27
28 for (i = 0; i < argc; ++i) { 28 for (i = 0; i < argc; ++i) {
29 struct map *map; 29 struct map *map;
30 struct symbol *symbol = machine__find_kernel_function_by_name(machine, argv[i], &map); 30 struct symbol *symbol = machine__find_kernel_symbol_by_name(machine, argv[i], &map);
31 31
32 if (symbol == NULL) { 32 if (symbol == NULL) {
33 printf("%s: not found\n", argv[i]); 33 printf("%s: not found\n", argv[i]);
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index ae11e4c3516a..54d3f21b0e62 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -1004,7 +1004,7 @@ static void __print_slab_result(struct rb_root *root,
1004 if (is_caller) { 1004 if (is_caller) {
1005 addr = data->call_site; 1005 addr = data->call_site;
1006 if (!raw_ip) 1006 if (!raw_ip)
1007 sym = machine__find_kernel_function(machine, addr, &map); 1007 sym = machine__find_kernel_symbol(machine, addr, &map);
1008 } else 1008 } else
1009 addr = data->ptr; 1009 addr = data->ptr;
1010 1010
@@ -1068,7 +1068,7 @@ static void __print_page_alloc_result(struct perf_session *session, int n_lines)
1068 char *caller = buf; 1068 char *caller = buf;
1069 1069
1070 data = rb_entry(next, struct page_stat, node); 1070 data = rb_entry(next, struct page_stat, node);
1071 sym = machine__find_kernel_function(machine, data->callsite, &map); 1071 sym = machine__find_kernel_symbol(machine, data->callsite, &map);
1072 if (sym) 1072 if (sym)
1073 caller = sym->name; 1073 caller = sym->name;
1074 else 1074 else
@@ -1110,7 +1110,7 @@ static void __print_page_caller_result(struct perf_session *session, int n_lines
1110 char *caller = buf; 1110 char *caller = buf;
1111 1111
1112 data = rb_entry(next, struct page_stat, node); 1112 data = rb_entry(next, struct page_stat, node);
1113 sym = machine__find_kernel_function(machine, data->callsite, &map); 1113 sym = machine__find_kernel_symbol(machine, data->callsite, &map);
1114 if (sym) 1114 if (sym)
1115 caller = sym->name; 1115 caller = sym->name;
1116 else 1116 else
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 0f198f6d9b77..4c931afb2e80 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -523,12 +523,9 @@ static void report__warn_kptr_restrict(const struct report *rep)
523 "As no suitable kallsyms nor vmlinux was found, kernel samples\n" 523 "As no suitable kallsyms nor vmlinux was found, kernel samples\n"
524 "can't be resolved."; 524 "can't be resolved.";
525 525
526 if (kernel_map) { 526 if (kernel_map && map__has_symbols(kernel_map)) {
527 const struct dso *kdso = kernel_map->dso; 527 desc = "If some relocation was applied (e.g. "
528 if (!RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION])) { 528 "kexec) symbols may be misresolved.";
529 desc = "If some relocation was applied (e.g. "
530 "kexec) symbols may be misresolved.";
531 }
532 } 529 }
533 530
534 ui__warning( 531 ui__warning(
@@ -718,10 +715,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
718 715
719static int map_groups__fprintf_task(struct map_groups *mg, int indent, FILE *fp) 716static int map_groups__fprintf_task(struct map_groups *mg, int indent, FILE *fp)
720{ 717{
721 int printed = 0, i; 718 return maps__fprintf_task(&mg->maps, indent, fp);
722 for (i = 0; i < MAP__NR_TYPES; ++i)
723 printed += maps__fprintf_task(&mg->maps[i], indent, fp);
724 return printed;
725} 719}
726 720
727static void task__print_level(struct task *task, FILE *fp, int level) 721static void task__print_level(struct task *task, FILE *fp, int level)
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index e0a9845b6cbc..fa2c7a288750 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -717,8 +717,8 @@ static int perf_sample__fprintf_brstack(struct perf_sample *sample,
717 if (PRINT_FIELD(DSO)) { 717 if (PRINT_FIELD(DSO)) {
718 memset(&alf, 0, sizeof(alf)); 718 memset(&alf, 0, sizeof(alf));
719 memset(&alt, 0, sizeof(alt)); 719 memset(&alt, 0, sizeof(alt));
720 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf); 720 thread__find_map(thread, sample->cpumode, from, &alf);
721 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); 721 thread__find_map(thread, sample->cpumode, to, &alt);
722 } 722 }
723 723
724 printed += fprintf(fp, " 0x%"PRIx64, from); 724 printed += fprintf(fp, " 0x%"PRIx64, from);
@@ -764,13 +764,8 @@ static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
764 from = br->entries[i].from; 764 from = br->entries[i].from;
765 to = br->entries[i].to; 765 to = br->entries[i].to;
766 766
767 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf); 767 thread__find_symbol(thread, sample->cpumode, from, &alf);
768 if (alf.map) 768 thread__find_symbol(thread, sample->cpumode, to, &alt);
769 alf.sym = map__find_symbol(alf.map, alf.addr);
770
771 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
772 if (alt.map)
773 alt.sym = map__find_symbol(alt.map, alt.addr);
774 769
775 printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp); 770 printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
776 if (PRINT_FIELD(DSO)) { 771 if (PRINT_FIELD(DSO)) {
@@ -814,12 +809,12 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
814 from = br->entries[i].from; 809 from = br->entries[i].from;
815 to = br->entries[i].to; 810 to = br->entries[i].to;
816 811
817 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf); 812 if (thread__find_map(thread, sample->cpumode, from, &alf) &&
818 if (alf.map && !alf.map->dso->adjust_symbols) 813 !alf.map->dso->adjust_symbols)
819 from = map__map_ip(alf.map, from); 814 from = map__map_ip(alf.map, from);
820 815
821 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); 816 if (thread__find_map(thread, sample->cpumode, to, &alt) &&
822 if (alt.map && !alt.map->dso->adjust_symbols) 817 !alt.map->dso->adjust_symbols)
823 to = map__map_ip(alt.map, to); 818 to = map__map_ip(alt.map, to);
824 819
825 printed += fprintf(fp, " 0x%"PRIx64, from); 820 printed += fprintf(fp, " 0x%"PRIx64, from);
@@ -882,8 +877,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
882 return 0; 877 return 0;
883 } 878 }
884 879
885 thread__find_addr_map(thread, *cpumode, MAP__FUNCTION, start, &al); 880 if (!thread__find_map(thread, *cpumode, start, &al) || !al.map->dso) {
886 if (!al.map || !al.map->dso) {
887 pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); 881 pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
888 return 0; 882 return 0;
889 } 883 }
@@ -933,10 +927,8 @@ static int ip__fprintf_sym(uint64_t addr, struct thread *thread,
933 927
934 memset(&al, 0, sizeof(al)); 928 memset(&al, 0, sizeof(al));
935 929
936 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, addr, &al); 930 thread__find_map(thread, cpumode, addr, &al);
937 if (!al.map) 931
938 thread__find_addr_map(thread, cpumode, MAP__VARIABLE,
939 addr, &al);
940 if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end) 932 if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
941 return 0; 933 return 0;
942 934
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index f17dc601b0f3..a4f662a462c6 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -164,6 +164,7 @@ static bool forever = false;
164static bool metric_only = false; 164static bool metric_only = false;
165static bool force_metric_only = false; 165static bool force_metric_only = false;
166static bool no_merge = false; 166static bool no_merge = false;
167static bool walltime_run_table = false;
167static struct timespec ref_time; 168static struct timespec ref_time;
168static struct cpu_map *aggr_map; 169static struct cpu_map *aggr_map;
169static aggr_get_id_t aggr_get_id; 170static aggr_get_id_t aggr_get_id;
@@ -173,6 +174,7 @@ static const char *output_name;
173static int output_fd; 174static int output_fd;
174static int print_free_counters_hint; 175static int print_free_counters_hint;
175static int print_mixed_hw_group_error; 176static int print_mixed_hw_group_error;
177static u64 *walltime_run;
176 178
177struct perf_stat { 179struct perf_stat {
178 bool record; 180 bool record;
@@ -569,7 +571,7 @@ static struct perf_evsel *perf_evsel__reset_weak_group(struct perf_evsel *evsel)
569 return leader; 571 return leader;
570} 572}
571 573
572static int __run_perf_stat(int argc, const char **argv) 574static int __run_perf_stat(int argc, const char **argv, int run_idx)
573{ 575{
574 int interval = stat_config.interval; 576 int interval = stat_config.interval;
575 int times = stat_config.times; 577 int times = stat_config.times;
@@ -752,6 +754,9 @@ try_again:
752 754
753 t1 = rdclock(); 755 t1 = rdclock();
754 756
757 if (walltime_run_table)
758 walltime_run[run_idx] = t1 - t0;
759
755 update_stats(&walltime_nsecs_stats, t1 - t0); 760 update_stats(&walltime_nsecs_stats, t1 - t0);
756 761
757 /* 762 /*
@@ -766,7 +771,7 @@ try_again:
766 return WEXITSTATUS(status); 771 return WEXITSTATUS(status);
767} 772}
768 773
769static int run_perf_stat(int argc, const char **argv) 774static int run_perf_stat(int argc, const char **argv, int run_idx)
770{ 775{
771 int ret; 776 int ret;
772 777
@@ -779,7 +784,7 @@ static int run_perf_stat(int argc, const char **argv)
779 if (sync_run) 784 if (sync_run)
780 sync(); 785 sync();
781 786
782 ret = __run_perf_stat(argc, argv); 787 ret = __run_perf_stat(argc, argv, run_idx);
783 if (ret) 788 if (ret)
784 return ret; 789 return ret;
785 790
@@ -1764,19 +1769,67 @@ static void print_header(int argc, const char **argv)
1764 } 1769 }
1765} 1770}
1766 1771
1772static int get_precision(double num)
1773{
1774 if (num > 1)
1775 return 0;
1776
1777 return lround(ceil(-log10(num)));
1778}
1779
1780static void print_table(FILE *output, int precision, double avg)
1781{
1782 char tmp[64];
1783 int idx, indent = 0;
1784
1785 scnprintf(tmp, 64, " %17.*f", precision, avg);
1786 while (tmp[indent] == ' ')
1787 indent++;
1788
1789 fprintf(output, "%*s# Table of individual measurements:\n", indent, "");
1790
1791 for (idx = 0; idx < run_count; idx++) {
1792 double run = (double) walltime_run[idx] / NSEC_PER_SEC;
1793 int h, n = 1 + abs((int) (100.0 * (run - avg)/run) / 5);
1794
1795 fprintf(output, " %17.*f (%+.*f) ",
1796 precision, run, precision, run - avg);
1797
1798 for (h = 0; h < n; h++)
1799 fprintf(output, "#");
1800
1801 fprintf(output, "\n");
1802 }
1803
1804 fprintf(output, "\n%*s# Final result:\n", indent, "");
1805}
1806
1767static void print_footer(void) 1807static void print_footer(void)
1768{ 1808{
1809 double avg = avg_stats(&walltime_nsecs_stats) / NSEC_PER_SEC;
1769 FILE *output = stat_config.output; 1810 FILE *output = stat_config.output;
1770 int n; 1811 int n;
1771 1812
1772 if (!null_run) 1813 if (!null_run)
1773 fprintf(output, "\n"); 1814 fprintf(output, "\n");
1774 fprintf(output, " %17.9f seconds time elapsed", 1815
1775 avg_stats(&walltime_nsecs_stats) / NSEC_PER_SEC); 1816 if (run_count == 1) {
1776 if (run_count > 1) { 1817 fprintf(output, " %17.9f seconds time elapsed", avg);
1777 fprintf(output, " "); 1818 } else {
1778 print_noise_pct(stddev_stats(&walltime_nsecs_stats), 1819 double sd = stddev_stats(&walltime_nsecs_stats) / NSEC_PER_SEC;
1779 avg_stats(&walltime_nsecs_stats)); 1820 /*
1821 * Display at most 2 more significant
1822 * digits than the stddev inaccuracy.
1823 */
1824 int precision = get_precision(sd) + 2;
1825
1826 if (walltime_run_table)
1827 print_table(output, precision, avg);
1828
1829 fprintf(output, " %17.*f +- %.*f seconds time elapsed",
1830 precision, avg, precision, sd);
1831
1832 print_noise_pct(sd, avg);
1780 } 1833 }
1781 fprintf(output, "\n\n"); 1834 fprintf(output, "\n\n");
1782 1835
@@ -1952,6 +2005,8 @@ static const struct option stat_options[] = {
1952 "be more verbose (show counter open errors, etc)"), 2005 "be more verbose (show counter open errors, etc)"),
1953 OPT_INTEGER('r', "repeat", &run_count, 2006 OPT_INTEGER('r', "repeat", &run_count,
1954 "repeat command and print average + stddev (max: 100, forever: 0)"), 2007 "repeat command and print average + stddev (max: 100, forever: 0)"),
2008 OPT_BOOLEAN(0, "table", &walltime_run_table,
2009 "display details about each run (only with -r option)"),
1955 OPT_BOOLEAN('n', "null", &null_run, 2010 OPT_BOOLEAN('n', "null", &null_run,
1956 "null run - dont start any counters"), 2011 "null run - dont start any counters"),
1957 OPT_INCR('d', "detailed", &detailed_run, 2012 OPT_INCR('d', "detailed", &detailed_run,
@@ -2843,6 +2898,13 @@ int cmd_stat(int argc, const char **argv)
2843 goto out; 2898 goto out;
2844 } 2899 }
2845 2900
2901 if (walltime_run_table && run_count <= 1) {
2902 fprintf(stderr, "--table is only supported with -r\n");
2903 parse_options_usage(stat_usage, stat_options, "r", 1);
2904 parse_options_usage(NULL, stat_options, "table", 0);
2905 goto out;
2906 }
2907
2846 if (output_fd < 0) { 2908 if (output_fd < 0) {
2847 fprintf(stderr, "argument to --log-fd must be a > 0\n"); 2909 fprintf(stderr, "argument to --log-fd must be a > 0\n");
2848 parse_options_usage(stat_usage, stat_options, "log-fd", 0); 2910 parse_options_usage(stat_usage, stat_options, "log-fd", 0);
@@ -2897,6 +2959,14 @@ int cmd_stat(int argc, const char **argv)
2897 run_count = 1; 2959 run_count = 1;
2898 } 2960 }
2899 2961
2962 if (walltime_run_table) {
2963 walltime_run = zalloc(run_count * sizeof(walltime_run[0]));
2964 if (!walltime_run) {
2965 pr_err("failed to setup -r option");
2966 goto out;
2967 }
2968 }
2969
2900 if ((stat_config.aggr_mode == AGGR_THREAD) && 2970 if ((stat_config.aggr_mode == AGGR_THREAD) &&
2901 !target__has_task(&target)) { 2971 !target__has_task(&target)) {
2902 if (!target.system_wide || target.cpu_list) { 2972 if (!target.system_wide || target.cpu_list) {
@@ -3012,7 +3082,7 @@ int cmd_stat(int argc, const char **argv)
3012 fprintf(output, "[ perf stat: executing run #%d ... ]\n", 3082 fprintf(output, "[ perf stat: executing run #%d ... ]\n",
3013 run_idx + 1); 3083 run_idx + 1);
3014 3084
3015 status = run_perf_stat(argc, argv); 3085 status = run_perf_stat(argc, argv, run_idx);
3016 if (forever && status != -1) { 3086 if (forever && status != -1) {
3017 print_counters(NULL, argc, argv); 3087 print_counters(NULL, argc, argv);
3018 perf_stat__reset_stats(); 3088 perf_stat__reset_stats();
@@ -3060,6 +3130,8 @@ int cmd_stat(int argc, const char **argv)
3060 perf_stat__exit_aggr_mode(); 3130 perf_stat__exit_aggr_mode();
3061 perf_evlist__free_stats(evsel_list); 3131 perf_evlist__free_stats(evsel_list);
3062out: 3132out:
3133 free(walltime_run);
3134
3063 if (smi_cost && smi_reset) 3135 if (smi_cost && smi_reset)
3064 sysfs__write_int(FREEZE_ON_SMI_PATH, 0); 3136 sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
3065 3137
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 813698a9b8c7..a827919c6263 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -533,12 +533,8 @@ static const char *cat_backtrace(union perf_event *event,
533 } 533 }
534 534
535 tal.filtered = 0; 535 tal.filtered = 0;
536 thread__find_addr_location(al.thread, cpumode, 536 if (thread__find_symbol(al.thread, cpumode, ip, &tal))
537 MAP__FUNCTION, ip, &tal); 537 fprintf(f, "..... %016" PRIx64 " %s\n", ip, tal.sym->name);
538
539 if (tal.sym)
540 fprintf(f, "..... %016" PRIx64 " %s\n", ip,
541 tal.sym->name);
542 else 538 else
543 fprintf(f, "..... %016" PRIx64 "\n", ip); 539 fprintf(f, "..... %016" PRIx64 "\n", ip);
544 } 540 }
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index f39bd60d2708..3c061c57afb6 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -742,7 +742,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
742"Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" 742"Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n"
743"Check /proc/sys/kernel/kptr_restrict.\n\n" 743"Check /proc/sys/kernel/kptr_restrict.\n\n"
744"Kernel%s samples will not be resolved.\n", 744"Kernel%s samples will not be resolved.\n",
745 al.map && !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ? 745 al.map && map__has_symbols(al.map) ?
746 " modules" : ""); 746 " modules" : "");
747 if (use_browser <= 0) 747 if (use_browser <= 0)
748 sleep(5); 748 sleep(5);
@@ -750,7 +750,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
750 machine->kptr_restrict_warned = true; 750 machine->kptr_restrict_warned = true;
751 } 751 }
752 752
753 if (al.sym == NULL) { 753 if (al.sym == NULL && al.map != NULL) {
754 const char *msg = "Kernel samples will not be resolved.\n"; 754 const char *msg = "Kernel samples will not be resolved.\n";
755 /* 755 /*
756 * As we do lazy loading of symtabs we only will know if the 756 * As we do lazy loading of symtabs we only will know if the
@@ -764,8 +764,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
764 * invalid --vmlinux ;-) 764 * invalid --vmlinux ;-)
765 */ 765 */
766 if (!machine->kptr_restrict_warned && !top->vmlinux_warned && 766 if (!machine->kptr_restrict_warned && !top->vmlinux_warned &&
767 al.map == machine->vmlinux_maps[MAP__FUNCTION] && 767 __map__is_kernel(al.map) && map__has_symbols(al.map)) {
768 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
769 if (symbol_conf.vmlinux_name) { 768 if (symbol_conf.vmlinux_name) {
770 char serr[256]; 769 char serr[256];
771 dso__strerror_load(al.map->dso, serr, sizeof(serr)); 770 dso__strerror_load(al.map->dso, serr, sizeof(serr));
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 3ad17ee89403..c7effcfc40ed 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2024,8 +2024,7 @@ static int trace__pgfault(struct trace *trace,
2024 if (trace->summary_only) 2024 if (trace->summary_only)
2025 goto out; 2025 goto out;
2026 2026
2027 thread__find_addr_location(thread, sample->cpumode, MAP__FUNCTION, 2027 thread__find_symbol(thread, sample->cpumode, sample->ip, &al);
2028 sample->ip, &al);
2029 2028
2030 trace__fprintf_entry_head(trace, thread, 0, true, sample->time, trace->output); 2029 trace__fprintf_entry_head(trace, thread, 0, true, sample->time, trace->output);
2031 2030
@@ -2037,12 +2036,10 @@ static int trace__pgfault(struct trace *trace,
2037 2036
2038 fprintf(trace->output, "] => "); 2037 fprintf(trace->output, "] => ");
2039 2038
2040 thread__find_addr_location(thread, sample->cpumode, MAP__VARIABLE, 2039 thread__find_symbol(thread, sample->cpumode, sample->addr, &al);
2041 sample->addr, &al);
2042 2040
2043 if (!al.map) { 2041 if (!al.map) {
2044 thread__find_addr_location(thread, sample->cpumode, 2042 thread__find_symbol(thread, sample->cpumode, sample->addr, &al);
2045 MAP__FUNCTION, sample->addr, &al);
2046 2043
2047 if (al.map) 2044 if (al.map)
2048 map_type = 'x'; 2045 map_type = 'x';
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 9aff89bc7535..10f333e2e825 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -55,22 +55,26 @@ include/uapi/asm-generic/ioctls.h
55include/uapi/asm-generic/mman-common.h 55include/uapi/asm-generic/mman-common.h
56' 56'
57 57
58check () { 58check_2 () {
59 file=$1 59 file1=$1
60 file2=$2
60 61
61 shift 62 shift
62 opts= 63 shift
63 while [ -n "$*" ]; do
64 opts="$opts \"$1\""
65 shift
66 done
67 64
68 cmd="diff $opts ../$file ../../$file > /dev/null" 65 cmd="diff $* $file1 $file2 > /dev/null"
69 66
70 test -f ../../$file && 67 test -f $file2 &&
71 eval $cmd || echo "Warning: Kernel ABI header at 'tools/$file' differs from latest version at '$file'" >&2 68 eval $cmd || echo "Warning: Kernel ABI header at 'tools/$file' differs from latest version at '$file'" >&2
72} 69}
73 70
71check () {
72 file=$1
73
74 shift
75
76 check_2 ../$file ../../$file $*
77}
74 78
75# Check if we have the kernel headers (tools/perf/../../include), else 79# Check if we have the kernel headers (tools/perf/../../include), else
76# we're probably on a detached tarball, so no point in trying to check 80# we're probably on a detached tarball, so no point in trying to check
@@ -83,7 +87,7 @@ for i in $HEADERS; do
83done 87done
84 88
85# diff with extra ignore lines 89# diff with extra ignore lines
86check arch/x86/lib/memcpy_64.S -I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" 90check arch/x86/lib/memcpy_64.S '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>"'
87check arch/x86/lib/memset_64.S -I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" 91check arch/x86/lib/memset_64.S '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>"'
88check include/uapi/asm-generic/mman.h -I "^#include <\(uapi/\)*asm-generic/mman-common.h>" 92check include/uapi/asm-generic/mman.h '-I "^#include <\(uapi/\)*asm-generic/mman-common.h>"'
89check include/uapi/linux/mman.h -I "^#include <\(uapi/\)*asm/mman.h>" 93check include/uapi/linux/mman.h '-I "^#include <\(uapi/\)*asm/mman.h>"'
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index cac8f8889bc3..2bde505e2e7e 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -654,6 +654,15 @@ static int perf_test__list(int argc, const char **argv)
654 continue; 654 continue;
655 655
656 pr_info("%2d: %s\n", i, t->desc); 656 pr_info("%2d: %s\n", i, t->desc);
657
658 if (t->subtest.get_nr) {
659 int subn = t->subtest.get_nr();
660 int subi;
661
662 for (subi = 0; subi < subn; subi++)
663 pr_info("%2d:%1d: %s\n", i, subi + 1,
664 t->subtest.get_desc(subi));
665 }
657 } 666 }
658 667
659 perf_test__list_shell(argc, argv, i); 668 perf_test__list_shell(argc, argv, i);
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 99936352df4f..afa4ce21ba7c 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -236,14 +236,13 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
236 236
237 pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); 237 pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
238 238
239 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, addr, &al); 239 if (!thread__find_map(thread, cpumode, addr, &al) || !al.map->dso) {
240 if (!al.map || !al.map->dso) {
241 if (cpumode == PERF_RECORD_MISC_HYPERVISOR) { 240 if (cpumode == PERF_RECORD_MISC_HYPERVISOR) {
242 pr_debug("Hypervisor address can not be resolved - skipping\n"); 241 pr_debug("Hypervisor address can not be resolved - skipping\n");
243 return 0; 242 return 0;
244 } 243 }
245 244
246 pr_debug("thread__find_addr_map failed\n"); 245 pr_debug("thread__find_map failed\n");
247 return -1; 246 return -1;
248 } 247 }
249 248
diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c
index f7c5b613d667..b889a28fd80b 100644
--- a/tools/perf/tests/hists_common.c
+++ b/tools/perf/tests/hists_common.c
@@ -131,20 +131,20 @@ struct machine *setup_fake_machine(struct machines *machines)
131 goto out; 131 goto out;
132 132
133 /* emulate dso__load() */ 133 /* emulate dso__load() */
134 dso__set_loaded(dso, MAP__FUNCTION); 134 dso__set_loaded(dso);
135 135
136 for (k = 0; k < fake_symbols[i].nr_syms; k++) { 136 for (k = 0; k < fake_symbols[i].nr_syms; k++) {
137 struct symbol *sym; 137 struct symbol *sym;
138 struct fake_sym *fsym = &fake_symbols[i].syms[k]; 138 struct fake_sym *fsym = &fake_symbols[i].syms[k];
139 139
140 sym = symbol__new(fsym->start, fsym->length, 140 sym = symbol__new(fsym->start, fsym->length,
141 STB_GLOBAL, fsym->name); 141 STB_GLOBAL, STT_FUNC, fsym->name);
142 if (sym == NULL) { 142 if (sym == NULL) {
143 dso__put(dso); 143 dso__put(dso);
144 goto out; 144 goto out;
145 } 145 }
146 146
147 symbols__insert(&dso->symbols[MAP__FUNCTION], sym); 147 symbols__insert(&dso->symbols, sym);
148 } 148 }
149 149
150 dso__put(dso); 150 dso__put(dso);
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c
index 868d82b501f4..b1af2499a3c9 100644
--- a/tools/perf/tests/mmap-thread-lookup.c
+++ b/tools/perf/tests/mmap-thread-lookup.c
@@ -188,9 +188,8 @@ static int mmap_events(synth_cb synth)
188 188
189 pr_debug("looking for map %p\n", td->map); 189 pr_debug("looking for map %p\n", td->map);
190 190
191 thread__find_addr_map(thread, 191 thread__find_map(thread, PERF_RECORD_MISC_USER,
192 PERF_RECORD_MISC_USER, MAP__FUNCTION, 192 (unsigned long) (td->map + 1), &al);
193 (unsigned long) (td->map + 1), &al);
194 193
195 thread__put(thread); 194 thread__put(thread);
196 195
@@ -218,7 +217,7 @@ static int mmap_events(synth_cb synth)
218 * perf_event__synthesize_threads (global) 217 * perf_event__synthesize_threads (global)
219 * 218 *
220 * We test we can find all memory maps via: 219 * We test we can find all memory maps via:
221 * thread__find_addr_map 220 * thread__find_map
222 * 221 *
223 * by using all thread objects. 222 * by using all thread objects.
224 */ 223 */
diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c
index 1e5adb65632a..7691980b7df1 100644
--- a/tools/perf/tests/vmlinux-kallsyms.c
+++ b/tools/perf/tests/vmlinux-kallsyms.c
@@ -19,8 +19,7 @@ int test__vmlinux_matches_kallsyms(struct test *test __maybe_unused, int subtest
19 struct symbol *sym; 19 struct symbol *sym;
20 struct map *kallsyms_map, *vmlinux_map, *map; 20 struct map *kallsyms_map, *vmlinux_map, *map;
21 struct machine kallsyms, vmlinux; 21 struct machine kallsyms, vmlinux;
22 enum map_type type = MAP__FUNCTION; 22 struct maps *maps = machine__kernel_maps(&vmlinux);
23 struct maps *maps = &vmlinux.kmaps.maps[type];
24 u64 mem_start, mem_end; 23 u64 mem_start, mem_end;
25 bool header_printed; 24 bool header_printed;
26 25
@@ -56,7 +55,7 @@ int test__vmlinux_matches_kallsyms(struct test *test __maybe_unused, int subtest
56 * be compacted against the list of modules found in the "vmlinux" 55 * be compacted against the list of modules found in the "vmlinux"
57 * code and with the one got from /proc/modules from the "kallsyms" code. 56 * code and with the one got from /proc/modules from the "kallsyms" code.
58 */ 57 */
59 if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type) <= 0) { 58 if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms") <= 0) {
60 pr_debug("dso__load_kallsyms "); 59 pr_debug("dso__load_kallsyms ");
61 goto out; 60 goto out;
62 } 61 }
@@ -94,7 +93,7 @@ int test__vmlinux_matches_kallsyms(struct test *test __maybe_unused, int subtest
94 * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines 93 * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines
95 * to fixup the symbols. 94 * to fixup the symbols.
96 */ 95 */
97 if (machine__load_vmlinux_path(&vmlinux, type) <= 0) { 96 if (machine__load_vmlinux_path(&vmlinux) <= 0) {
98 pr_debug("Couldn't find a vmlinux that matches the kernel running on this machine, skipping test\n"); 97 pr_debug("Couldn't find a vmlinux that matches the kernel running on this machine, skipping test\n");
99 err = TEST_SKIP; 98 err = TEST_SKIP;
100 goto out; 99 goto out;
@@ -108,7 +107,7 @@ int test__vmlinux_matches_kallsyms(struct test *test __maybe_unused, int subtest
108 * in the kallsyms dso. For the ones that are in both, check its names and 107 * in the kallsyms dso. For the ones that are in both, check its names and
109 * end addresses too. 108 * end addresses too.
110 */ 109 */
111 for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) { 110 map__for_each_symbol(vmlinux_map, sym, nd) {
112 struct symbol *pair, *first_pair; 111 struct symbol *pair, *first_pair;
113 112
114 sym = rb_entry(nd, struct symbol, rb_node); 113 sym = rb_entry(nd, struct symbol, rb_node);
@@ -119,8 +118,7 @@ int test__vmlinux_matches_kallsyms(struct test *test __maybe_unused, int subtest
119 mem_start = vmlinux_map->unmap_ip(vmlinux_map, sym->start); 118 mem_start = vmlinux_map->unmap_ip(vmlinux_map, sym->start);
120 mem_end = vmlinux_map->unmap_ip(vmlinux_map, sym->end); 119 mem_end = vmlinux_map->unmap_ip(vmlinux_map, sym->end);
121 120
122 first_pair = machine__find_kernel_symbol(&kallsyms, type, 121 first_pair = machine__find_kernel_symbol(&kallsyms, mem_start, NULL);
123 mem_start, NULL);
124 pair = first_pair; 122 pair = first_pair;
125 123
126 if (pair && UM(pair->start) == mem_start) { 124 if (pair && UM(pair->start) == mem_start) {
@@ -149,7 +147,7 @@ next_pair:
149 */ 147 */
150 continue; 148 continue;
151 } else { 149 } else {
152 pair = machine__find_kernel_symbol_by_name(&kallsyms, type, sym->name, NULL); 150 pair = machine__find_kernel_symbol_by_name(&kallsyms, sym->name, NULL);
153 if (pair) { 151 if (pair) {
154 if (UM(pair->start) == mem_start) 152 if (UM(pair->start) == mem_start)
155 goto next_pair; 153 goto next_pair;
@@ -183,7 +181,7 @@ next_pair:
183 * so use the short name, less descriptive but the same ("[kernel]" in 181 * so use the short name, less descriptive but the same ("[kernel]" in
184 * both cases. 182 * both cases.
185 */ 183 */
186 pair = map_groups__find_by_name(&kallsyms.kmaps, type, 184 pair = map_groups__find_by_name(&kallsyms.kmaps,
187 (map->dso->kernel ? 185 (map->dso->kernel ?
188 map->dso->short_name : 186 map->dso->short_name :
189 map->dso->name)); 187 map->dso->name));
@@ -206,7 +204,7 @@ next_pair:
206 mem_start = vmlinux_map->unmap_ip(vmlinux_map, map->start); 204 mem_start = vmlinux_map->unmap_ip(vmlinux_map, map->start);
207 mem_end = vmlinux_map->unmap_ip(vmlinux_map, map->end); 205 mem_end = vmlinux_map->unmap_ip(vmlinux_map, map->end);
208 206
209 pair = map_groups__find(&kallsyms.kmaps, type, mem_start); 207 pair = map_groups__find(&kallsyms.kmaps, mem_start);
210 if (pair == NULL || pair->priv) 208 if (pair == NULL || pair->priv)
211 continue; 209 continue;
212 210
@@ -228,7 +226,7 @@ next_pair:
228 226
229 header_printed = false; 227 header_printed = false;
230 228
231 maps = &kallsyms.kmaps.maps[type]; 229 maps = machine__kernel_maps(&kallsyms);
232 230
233 for (map = maps__first(maps); map; map = map__next(map)) { 231 for (map = maps__first(maps); map; map = map__next(map)) {
234 if (!map->priv) { 232 if (!map->priv) {
diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c
index e03fa75f108a..5b8b8c637686 100644
--- a/tools/perf/ui/browsers/map.c
+++ b/tools/perf/ui/browsers/map.c
@@ -104,7 +104,7 @@ int map__browse(struct map *map)
104{ 104{
105 struct map_browser mb = { 105 struct map_browser mb = {
106 .b = { 106 .b = {
107 .entries = &map->dso->symbols[map->type], 107 .entries = &map->dso->symbols,
108 .refresh = ui_browser__rb_tree_refresh, 108 .refresh = ui_browser__rb_tree_refresh,
109 .seek = ui_browser__rb_tree_seek, 109 .seek = ui_browser__rb_tree_seek,
110 .write = map_browser__write, 110 .write = map_browser__write,
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 6832fcb2e6ff..c1eb476da91b 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -819,8 +819,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
819 } 819 }
820 820
821 if (h->ms.map == NULL && verbose > 1) { 821 if (h->ms.map == NULL && verbose > 1) {
822 __map_groups__fprintf_maps(h->thread->mg, 822 map_groups__fprintf(h->thread->mg, fp);
823 MAP__FUNCTION, fp);
824 fprintf(fp, "%.10s end\n", graph_dotted_line); 823 fprintf(fp, "%.10s end\n", graph_dotted_line);
825 } 824 }
826 } 825 }
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 857de69a5361..d056447520a2 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -1679,7 +1679,7 @@ struct sym_args {
1679static bool kern_sym_match(struct sym_args *args, const char *name, char type) 1679static bool kern_sym_match(struct sym_args *args, const char *name, char type)
1680{ 1680{
1681 /* A function with the same name, and global or the n'th found or any */ 1681 /* A function with the same name, and global or the n'th found or any */
1682 return symbol_type__is_a(type, MAP__FUNCTION) && 1682 return kallsyms__is_function(type) &&
1683 !strcmp(name, args->name) && 1683 !strcmp(name, args->name) &&
1684 ((args->global && isupper(type)) || 1684 ((args->global && isupper(type)) ||
1685 (args->selected && ++(args->cnt) == args->idx) || 1685 (args->selected && ++(args->cnt) == args->idx) ||
@@ -1784,7 +1784,7 @@ static int find_entire_kern_cb(void *arg, const char *name __maybe_unused,
1784{ 1784{
1785 struct sym_args *args = arg; 1785 struct sym_args *args = arg;
1786 1786
1787 if (!symbol_type__is_a(type, MAP__FUNCTION)) 1787 if (!kallsyms__is_function(type))
1788 return 0; 1788 return 0;
1789 1789
1790 if (!args->started) { 1790 if (!args->started) {
@@ -1915,7 +1915,7 @@ static void print_duplicate_syms(struct dso *dso, const char *sym_name)
1915 1915
1916 pr_err("Multiple symbols with name '%s'\n", sym_name); 1916 pr_err("Multiple symbols with name '%s'\n", sym_name);
1917 1917
1918 sym = dso__first_symbol(dso, MAP__FUNCTION); 1918 sym = dso__first_symbol(dso);
1919 while (sym) { 1919 while (sym) {
1920 if (dso_sym_match(sym, sym_name, &cnt, -1)) { 1920 if (dso_sym_match(sym, sym_name, &cnt, -1)) {
1921 pr_err("#%d\t0x%"PRIx64"\t%c\t%s\n", 1921 pr_err("#%d\t0x%"PRIx64"\t%c\t%s\n",
@@ -1945,7 +1945,7 @@ static int find_dso_sym(struct dso *dso, const char *sym_name, u64 *start,
1945 *start = 0; 1945 *start = 0;
1946 *size = 0; 1946 *size = 0;
1947 1947
1948 sym = dso__first_symbol(dso, MAP__FUNCTION); 1948 sym = dso__first_symbol(dso);
1949 while (sym) { 1949 while (sym) {
1950 if (*start) { 1950 if (*start) {
1951 if (!*size) 1951 if (!*size)
@@ -1972,8 +1972,8 @@ static int find_dso_sym(struct dso *dso, const char *sym_name, u64 *start,
1972 1972
1973static int addr_filter__entire_dso(struct addr_filter *filt, struct dso *dso) 1973static int addr_filter__entire_dso(struct addr_filter *filt, struct dso *dso)
1974{ 1974{
1975 struct symbol *first_sym = dso__first_symbol(dso, MAP__FUNCTION); 1975 struct symbol *first_sym = dso__first_symbol(dso);
1976 struct symbol *last_sym = dso__last_symbol(dso, MAP__FUNCTION); 1976 struct symbol *last_sym = dso__last_symbol(dso);
1977 1977
1978 if (!first_sym || !last_sym) { 1978 if (!first_sym || !last_sym) {
1979 pr_err("Failed to determine filter for %s\nNo symbols found.\n", 1979 pr_err("Failed to determine filter for %s\nNo symbols found.\n",
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 537eadd81914..04b1d53e4bf9 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -47,9 +47,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
47 return -1; 47 return -1;
48 } 48 }
49 49
50 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, &al); 50 if (thread__find_map(thread, sample->cpumode, sample->ip, &al))
51
52 if (al.map != NULL)
53 al.map->dso->hit = 1; 51 al.map->dso->hit = 1;
54 52
55 thread__put(thread); 53 thread__put(thread);
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 40020b1ca54f..6533b1adb50b 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -269,9 +269,7 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u64 address,
269 thread = etmq->etm->unknown_thread; 269 thread = etmq->etm->unknown_thread;
270 } 270 }
271 271
272 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, address, &al); 272 if (!thread__find_map(thread, cpumode, address, &al) || !al.map->dso)
273
274 if (!al.map || !al.map->dso)
275 return 0; 273 return 0;
276 274
277 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR && 275 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c
index b0c2b5c5d337..7123746edcf4 100644
--- a/tools/perf/util/db-export.c
+++ b/tools/perf/util/db-export.c
@@ -247,9 +247,9 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al,
247 *dso_db_id = dso->db_id; 247 *dso_db_id = dso->db_id;
248 248
249 if (!al->sym) { 249 if (!al->sym) {
250 al->sym = symbol__new(al->addr, 0, 0, "unknown"); 250 al->sym = symbol__new(al->addr, 0, 0, 0, "unknown");
251 if (al->sym) 251 if (al->sym)
252 dso__insert_symbol(dso, al->map->type, al->sym); 252 dso__insert_symbol(dso, al->sym);
253 } 253 }
254 254
255 if (al->sym) { 255 if (al->sym) {
@@ -315,8 +315,7 @@ static struct call_path *call_path_from_sample(struct db_export *dbe,
315 al.addr = node->ip; 315 al.addr = node->ip;
316 316
317 if (al.map && !al.sym) 317 if (al.map && !al.sym)
318 al.sym = dso__find_symbol(al.map->dso, MAP__FUNCTION, 318 al.sym = dso__find_symbol(al.map->dso, al.addr);
319 al.addr);
320 319
321 db_ids_from_al(dbe, &al, &dso_db_id, &sym_db_id, &offset); 320 db_ids_from_al(dbe, &al, &dso_db_id, &sym_db_id, &offset);
322 321
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 36ef45b2e89d..cdfc2e5f55f5 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -1014,7 +1014,7 @@ struct map *dso__new_map(const char *name)
1014 struct dso *dso = dso__new(name); 1014 struct dso *dso = dso__new(name);
1015 1015
1016 if (dso) 1016 if (dso)
1017 map = map__new2(0, dso, MAP__FUNCTION); 1017 map = map__new2(0, dso);
1018 1018
1019 return map; 1019 return map;
1020} 1020}
@@ -1176,19 +1176,19 @@ int dso__name_len(const struct dso *dso)
1176 return dso->short_name_len; 1176 return dso->short_name_len;
1177} 1177}
1178 1178
1179bool dso__loaded(const struct dso *dso, enum map_type type) 1179bool dso__loaded(const struct dso *dso)
1180{ 1180{
1181 return dso->loaded & (1 << type); 1181 return dso->loaded;
1182} 1182}
1183 1183
1184bool dso__sorted_by_name(const struct dso *dso, enum map_type type) 1184bool dso__sorted_by_name(const struct dso *dso)
1185{ 1185{
1186 return dso->sorted_by_name & (1 << type); 1186 return dso->sorted_by_name;
1187} 1187}
1188 1188
1189void dso__set_sorted_by_name(struct dso *dso, enum map_type type) 1189void dso__set_sorted_by_name(struct dso *dso)
1190{ 1190{
1191 dso->sorted_by_name |= (1 << type); 1191 dso->sorted_by_name = true;
1192} 1192}
1193 1193
1194struct dso *dso__new(const char *name) 1194struct dso *dso__new(const char *name)
@@ -1196,12 +1196,10 @@ struct dso *dso__new(const char *name)
1196 struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1); 1196 struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
1197 1197
1198 if (dso != NULL) { 1198 if (dso != NULL) {
1199 int i;
1200 strcpy(dso->name, name); 1199 strcpy(dso->name, name);
1201 dso__set_long_name(dso, dso->name, false); 1200 dso__set_long_name(dso, dso->name, false);
1202 dso__set_short_name(dso, dso->name, false); 1201 dso__set_short_name(dso, dso->name, false);
1203 for (i = 0; i < MAP__NR_TYPES; ++i) 1202 dso->symbols = dso->symbol_names = RB_ROOT;
1204 dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
1205 dso->data.cache = RB_ROOT; 1203 dso->data.cache = RB_ROOT;
1206 dso->inlined_nodes = RB_ROOT; 1204 dso->inlined_nodes = RB_ROOT;
1207 dso->srclines = RB_ROOT; 1205 dso->srclines = RB_ROOT;
@@ -1231,8 +1229,6 @@ struct dso *dso__new(const char *name)
1231 1229
1232void dso__delete(struct dso *dso) 1230void dso__delete(struct dso *dso)
1233{ 1231{
1234 int i;
1235
1236 if (!RB_EMPTY_NODE(&dso->rb_node)) 1232 if (!RB_EMPTY_NODE(&dso->rb_node))
1237 pr_err("DSO %s is still in rbtree when being deleted!\n", 1233 pr_err("DSO %s is still in rbtree when being deleted!\n",
1238 dso->long_name); 1234 dso->long_name);
@@ -1240,8 +1236,7 @@ void dso__delete(struct dso *dso)
1240 /* free inlines first, as they reference symbols */ 1236 /* free inlines first, as they reference symbols */
1241 inlines__tree_delete(&dso->inlined_nodes); 1237 inlines__tree_delete(&dso->inlined_nodes);
1242 srcline__tree_delete(&dso->srclines); 1238 srcline__tree_delete(&dso->srclines);
1243 for (i = 0; i < MAP__NR_TYPES; ++i) 1239 symbols__delete(&dso->symbols);
1244 symbols__delete(&dso->symbols[i]);
1245 1240
1246 if (dso->short_name_allocated) { 1241 if (dso->short_name_allocated) {
1247 zfree((char **)&dso->short_name); 1242 zfree((char **)&dso->short_name);
@@ -1451,9 +1446,7 @@ size_t __dsos__fprintf(struct list_head *head, FILE *fp)
1451 size_t ret = 0; 1446 size_t ret = 0;
1452 1447
1453 list_for_each_entry(pos, head, node) { 1448 list_for_each_entry(pos, head, node) {
1454 int i; 1449 ret += dso__fprintf(pos, fp);
1455 for (i = 0; i < MAP__NR_TYPES; ++i)
1456 ret += dso__fprintf(pos, i, fp);
1457 } 1450 }
1458 1451
1459 return ret; 1452 return ret;
@@ -1467,18 +1460,17 @@ size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
1467 return fprintf(fp, "%s", sbuild_id); 1460 return fprintf(fp, "%s", sbuild_id);
1468} 1461}
1469 1462
1470size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp) 1463size_t dso__fprintf(struct dso *dso, FILE *fp)
1471{ 1464{
1472 struct rb_node *nd; 1465 struct rb_node *nd;
1473 size_t ret = fprintf(fp, "dso: %s (", dso->short_name); 1466 size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
1474 1467
1475 if (dso->short_name != dso->long_name) 1468 if (dso->short_name != dso->long_name)
1476 ret += fprintf(fp, "%s, ", dso->long_name); 1469 ret += fprintf(fp, "%s, ", dso->long_name);
1477 ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type], 1470 ret += fprintf(fp, "%sloaded, ", dso__loaded(dso) ? "" : "NOT ");
1478 dso__loaded(dso, type) ? "" : "NOT ");
1479 ret += dso__fprintf_buildid(dso, fp); 1471 ret += dso__fprintf_buildid(dso, fp);
1480 ret += fprintf(fp, ")\n"); 1472 ret += fprintf(fp, ")\n");
1481 for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) { 1473 for (nd = rb_first(&dso->symbols); nd; nd = rb_next(nd)) {
1482 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 1474 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
1483 ret += symbol__fprintf(pos, fp); 1475 ret += symbol__fprintf(pos, fp);
1484 } 1476 }
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index c229dbe0277a..ef69de2e69ea 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -140,14 +140,14 @@ struct dso {
140 struct list_head node; 140 struct list_head node;
141 struct rb_node rb_node; /* rbtree node sorted by long name */ 141 struct rb_node rb_node; /* rbtree node sorted by long name */
142 struct rb_root *root; /* root of rbtree that rb_node is in */ 142 struct rb_root *root; /* root of rbtree that rb_node is in */
143 struct rb_root symbols[MAP__NR_TYPES]; 143 struct rb_root symbols;
144 struct rb_root symbol_names[MAP__NR_TYPES]; 144 struct rb_root symbol_names;
145 struct rb_root inlined_nodes; 145 struct rb_root inlined_nodes;
146 struct rb_root srclines; 146 struct rb_root srclines;
147 struct { 147 struct {
148 u64 addr; 148 u64 addr;
149 struct symbol *symbol; 149 struct symbol *symbol;
150 } last_find_result[MAP__NR_TYPES]; 150 } last_find_result;
151 void *a2l; 151 void *a2l;
152 char *symsrc_filename; 152 char *symsrc_filename;
153 unsigned int a2l_fails; 153 unsigned int a2l_fails;
@@ -164,8 +164,8 @@ struct dso {
164 u8 short_name_allocated:1; 164 u8 short_name_allocated:1;
165 u8 long_name_allocated:1; 165 u8 long_name_allocated:1;
166 u8 is_64_bit:1; 166 u8 is_64_bit:1;
167 u8 sorted_by_name; 167 bool sorted_by_name;
168 u8 loaded; 168 bool loaded;
169 u8 rel; 169 u8 rel;
170 u8 build_id[BUILD_ID_SIZE]; 170 u8 build_id[BUILD_ID_SIZE];
171 u64 text_offset; 171 u64 text_offset;
@@ -202,14 +202,13 @@ struct dso {
202 * @dso: the 'struct dso *' in which symbols itereated 202 * @dso: the 'struct dso *' in which symbols itereated
203 * @pos: the 'struct symbol *' to use as a loop cursor 203 * @pos: the 'struct symbol *' to use as a loop cursor
204 * @n: the 'struct rb_node *' to use as a temporary storage 204 * @n: the 'struct rb_node *' to use as a temporary storage
205 * @type: the 'enum map_type' type of symbols
206 */ 205 */
207#define dso__for_each_symbol(dso, pos, n, type) \ 206#define dso__for_each_symbol(dso, pos, n) \
208 symbols__for_each_entry(&(dso)->symbols[(type)], pos, n) 207 symbols__for_each_entry(&(dso)->symbols, pos, n)
209 208
210static inline void dso__set_loaded(struct dso *dso, enum map_type type) 209static inline void dso__set_loaded(struct dso *dso)
211{ 210{
212 dso->loaded |= (1 << type); 211 dso->loaded = true;
213} 212}
214 213
215struct dso *dso__new(const char *name); 214struct dso *dso__new(const char *name);
@@ -231,11 +230,16 @@ static inline void __dso__zput(struct dso **dso)
231 230
232#define dso__zput(dso) __dso__zput(&dso) 231#define dso__zput(dso) __dso__zput(&dso)
233 232
234bool dso__loaded(const struct dso *dso, enum map_type type); 233bool dso__loaded(const struct dso *dso);
235 234
236bool dso__sorted_by_name(const struct dso *dso, enum map_type type); 235static inline bool dso__has_symbols(const struct dso *dso)
237void dso__set_sorted_by_name(struct dso *dso, enum map_type type); 236{
238void dso__sort_by_name(struct dso *dso, enum map_type type); 237 return !RB_EMPTY_ROOT(&dso->symbols);
238}
239
240bool dso__sorted_by_name(const struct dso *dso);
241void dso__set_sorted_by_name(struct dso *dso);
242void dso__sort_by_name(struct dso *dso);
239 243
240void dso__set_build_id(struct dso *dso, void *build_id); 244void dso__set_build_id(struct dso *dso, void *build_id);
241bool dso__build_id_equal(const struct dso *dso, u8 *build_id); 245bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
@@ -349,9 +353,8 @@ size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
349size_t __dsos__fprintf(struct list_head *head, FILE *fp); 353size_t __dsos__fprintf(struct list_head *head, FILE *fp);
350 354
351size_t dso__fprintf_buildid(struct dso *dso, FILE *fp); 355size_t dso__fprintf_buildid(struct dso *dso, FILE *fp);
352size_t dso__fprintf_symbols_by_name(struct dso *dso, 356size_t dso__fprintf_symbols_by_name(struct dso *dso, FILE *fp);
353 enum map_type type, FILE *fp); 357size_t dso__fprintf(struct dso *dso, FILE *fp);
354size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
355 358
356static inline bool dso__is_vmlinux(struct dso *dso) 359static inline bool dso__is_vmlinux(struct dso *dso)
357{ 360{
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 98ff3a6a3d50..244135b5ea43 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -464,8 +464,7 @@ int perf_event__synthesize_modules(struct perf_tool *tool,
464{ 464{
465 int rc = 0; 465 int rc = 0;
466 struct map *pos; 466 struct map *pos;
467 struct map_groups *kmaps = &machine->kmaps; 467 struct maps *maps = machine__kernel_maps(machine);
468 struct maps *maps = &kmaps->maps[MAP__FUNCTION];
469 union perf_event *event = zalloc((sizeof(event->mmap) + 468 union perf_event *event = zalloc((sizeof(event->mmap) +
470 machine->id_hdr_size)); 469 machine->id_hdr_size));
471 if (event == NULL) { 470 if (event == NULL) {
@@ -869,7 +868,7 @@ static int find_symbol_cb(void *arg, const char *name, char type,
869 * Must be a function or at least an alias, as in PARISC64, where "_text" is 868 * Must be a function or at least an alias, as in PARISC64, where "_text" is
870 * an 'A' to the same address as "_stext". 869 * an 'A' to the same address as "_stext".
871 */ 870 */
872 if (!(symbol_type__is_a(type, MAP__FUNCTION) || 871 if (!(kallsyms__is_function(type) ||
873 type == 'A') || strcmp(name, args->name)) 872 type == 'A') || strcmp(name, args->name))
874 return 0; 873 return 0;
875 874
@@ -1489,9 +1488,8 @@ int perf_event__process(struct perf_tool *tool __maybe_unused,
1489 return machine__process_event(machine, event, sample); 1488 return machine__process_event(machine, event, sample);
1490} 1489}
1491 1490
1492void thread__find_addr_map(struct thread *thread, u8 cpumode, 1491struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
1493 enum map_type type, u64 addr, 1492 struct addr_location *al)
1494 struct addr_location *al)
1495{ 1493{
1496 struct map_groups *mg = thread->mg; 1494 struct map_groups *mg = thread->mg;
1497 struct machine *machine = mg->machine; 1495 struct machine *machine = mg->machine;
@@ -1505,7 +1503,7 @@ void thread__find_addr_map(struct thread *thread, u8 cpumode,
1505 1503
1506 if (machine == NULL) { 1504 if (machine == NULL) {
1507 al->map = NULL; 1505 al->map = NULL;
1508 return; 1506 return NULL;
1509 } 1507 }
1510 1508
1511 if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { 1509 if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
@@ -1533,10 +1531,10 @@ void thread__find_addr_map(struct thread *thread, u8 cpumode,
1533 !perf_host) 1531 !perf_host)
1534 al->filtered |= (1 << HIST_FILTER__HOST); 1532 al->filtered |= (1 << HIST_FILTER__HOST);
1535 1533
1536 return; 1534 return NULL;
1537 } 1535 }
1538try_again: 1536try_again:
1539 al->map = map_groups__find(mg, type, al->addr); 1537 al->map = map_groups__find(mg, al->addr);
1540 if (al->map == NULL) { 1538 if (al->map == NULL) {
1541 /* 1539 /*
1542 * If this is outside of all known maps, and is a negative 1540 * If this is outside of all known maps, and is a negative
@@ -1563,17 +1561,17 @@ try_again:
1563 map__load(al->map); 1561 map__load(al->map);
1564 al->addr = al->map->map_ip(al->map, al->addr); 1562 al->addr = al->map->map_ip(al->map, al->addr);
1565 } 1563 }
1564
1565 return al->map;
1566} 1566}
1567 1567
1568void thread__find_addr_location(struct thread *thread, 1568struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
1569 u8 cpumode, enum map_type type, u64 addr, 1569 u64 addr, struct addr_location *al)
1570 struct addr_location *al)
1571{ 1570{
1572 thread__find_addr_map(thread, cpumode, type, addr, al); 1571 al->sym = NULL;
1573 if (al->map != NULL) 1572 if (thread__find_map(thread, cpumode, addr, al))
1574 al->sym = map__find_symbol(al->map, al->addr); 1573 al->sym = map__find_symbol(al->map, al->addr);
1575 else 1574 return al->sym;
1576 al->sym = NULL;
1577} 1575}
1578 1576
1579/* 1577/*
@@ -1590,7 +1588,7 @@ int machine__resolve(struct machine *machine, struct addr_location *al,
1590 return -1; 1588 return -1;
1591 1589
1592 dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid); 1590 dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
1593 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, al); 1591 thread__find_map(thread, sample->cpumode, sample->ip, al);
1594 dump_printf(" ...... dso: %s\n", 1592 dump_printf(" ...... dso: %s\n",
1595 al->map ? al->map->dso->long_name : 1593 al->map ? al->map->dso->long_name :
1596 al->level == 'H' ? "[hypervisor]" : "<not found>"); 1594 al->level == 'H' ? "[hypervisor]" : "<not found>");
@@ -1669,10 +1667,7 @@ bool sample_addr_correlates_sym(struct perf_event_attr *attr)
1669void thread__resolve(struct thread *thread, struct addr_location *al, 1667void thread__resolve(struct thread *thread, struct addr_location *al,
1670 struct perf_sample *sample) 1668 struct perf_sample *sample)
1671{ 1669{
1672 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->addr, al); 1670 thread__find_map(thread, sample->cpumode, sample->addr, al);
1673 if (!al->map)
1674 thread__find_addr_map(thread, sample->cpumode, MAP__VARIABLE,
1675 sample->addr, al);
1676 1671
1677 al->cpu = sample->cpu; 1672 al->cpu = sample->cpu;
1678 al->sym = NULL; 1673 al->sym = NULL;
diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c
index c540d47583e7..aafbe54fd3fa 100644
--- a/tools/perf/util/genelf.c
+++ b/tools/perf/util/genelf.c
@@ -114,7 +114,7 @@ gen_build_id(struct buildid_note *note,
114 114
115 fd = open("/dev/urandom", O_RDONLY); 115 fd = open("/dev/urandom", O_RDONLY);
116 if (fd == -1) 116 if (fd == -1)
117 err(1, "cannot access /dev/urandom for builid"); 117 err(1, "cannot access /dev/urandom for buildid");
118 118
119 sret = read(fd, note->build_id, sz); 119 sret = read(fd, note->build_id, sz);
120 120
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index 72db2744876d..7f0c83b6332b 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -335,8 +335,7 @@ static int intel_bts_get_next_insn(struct intel_bts_queue *btsq, u64 ip)
335 if (!thread) 335 if (!thread)
336 return -1; 336 return -1;
337 337
338 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, ip, &al); 338 if (!thread__find_map(thread, cpumode, ip, &al) || !al.map->dso)
339 if (!al.map || !al.map->dso)
340 goto out_put; 339 goto out_put;
341 340
342 len = dso__data_read_addr(al.map->dso, al.map, machine, ip, buf, 341 len = dso__data_read_addr(al.map->dso, al.map, machine, ip, buf,
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 0effaff57020..492986a25ef6 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -442,8 +442,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
442 } 442 }
443 443
444 while (1) { 444 while (1) {
445 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, *ip, &al); 445 if (!thread__find_map(thread, cpumode, *ip, &al) || !al.map->dso)
446 if (!al.map || !al.map->dso)
447 return -EINVAL; 446 return -EINVAL;
448 447
449 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR && 448 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
@@ -596,8 +595,7 @@ static int __intel_pt_pgd_ip(uint64_t ip, void *data)
596 if (!thread) 595 if (!thread)
597 return -EINVAL; 596 return -EINVAL;
598 597
599 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, ip, &al); 598 if (!thread__find_map(thread, cpumode, ip, &al) || !al.map->dso)
600 if (!al.map || !al.map->dso)
601 return -EINVAL; 599 return -EINVAL;
602 600
603 offset = al.map->map_ip(al.map, ip); 601 offset = al.map->map_ip(al.map, ip);
@@ -1565,7 +1563,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip)
1565 if (map__load(map)) 1563 if (map__load(map))
1566 return 0; 1564 return 0;
1567 1565
1568 start = dso__first_symbol(map->dso, MAP__FUNCTION); 1566 start = dso__first_symbol(map->dso);
1569 1567
1570 for (sym = start; sym; sym = dso__next_symbol(sym)) { 1568 for (sym = start; sym; sym = dso__next_symbol(sym)) {
1571 if (sym->binding == STB_GLOBAL && 1569 if (sym->binding == STB_GLOBAL &&
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 32d50492505d..72a351613d85 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -24,6 +24,7 @@
24 24
25#include "sane_ctype.h" 25#include "sane_ctype.h"
26#include <symbol/kallsyms.h> 26#include <symbol/kallsyms.h>
27#include <linux/mman.h>
27 28
28static void __machine__remove_thread(struct machine *machine, struct thread *th, bool lock); 29static void __machine__remove_thread(struct machine *machine, struct thread *th, bool lock);
29 30
@@ -81,8 +82,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
81 machine->kptr_restrict_warned = false; 82 machine->kptr_restrict_warned = false;
82 machine->comm_exec = false; 83 machine->comm_exec = false;
83 machine->kernel_start = 0; 84 machine->kernel_start = 0;
84 85 machine->vmlinux_map = NULL;
85 memset(machine->vmlinux_maps, 0, sizeof(machine->vmlinux_maps));
86 86
87 machine->root_dir = strdup(root_dir); 87 machine->root_dir = strdup(root_dir);
88 if (machine->root_dir == NULL) 88 if (machine->root_dir == NULL)
@@ -137,13 +137,11 @@ struct machine *machine__new_kallsyms(void)
137 struct machine *machine = machine__new_host(); 137 struct machine *machine = machine__new_host();
138 /* 138 /*
139 * FIXME: 139 * FIXME:
140 * 1) MAP__FUNCTION will go away when we stop loading separate maps for 140 * 1) We should switch to machine__load_kallsyms(), i.e. not explicitely
141 * functions and data objects.
142 * 2) We should switch to machine__load_kallsyms(), i.e. not explicitely
143 * ask for not using the kcore parsing code, once this one is fixed 141 * ask for not using the kcore parsing code, once this one is fixed
144 * to create a map per module. 142 * to create a map per module.
145 */ 143 */
146 if (machine && machine__load_kallsyms(machine, "/proc/kallsyms", MAP__FUNCTION) <= 0) { 144 if (machine && machine__load_kallsyms(machine, "/proc/kallsyms") <= 0) {
147 machine__delete(machine); 145 machine__delete(machine);
148 machine = NULL; 146 machine = NULL;
149 } 147 }
@@ -673,8 +671,7 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start,
673 if (kmod_path__parse_name(&m, filename)) 671 if (kmod_path__parse_name(&m, filename))
674 return NULL; 672 return NULL;
675 673
676 map = map_groups__find_by_name(&machine->kmaps, MAP__FUNCTION, 674 map = map_groups__find_by_name(&machine->kmaps, m.name);
677 m.name);
678 if (map) { 675 if (map) {
679 /* 676 /*
680 * If the map's dso is an offline module, give dso__load() 677 * If the map's dso is an offline module, give dso__load()
@@ -689,7 +686,7 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start,
689 if (dso == NULL) 686 if (dso == NULL)
690 goto out; 687 goto out;
691 688
692 map = map__new2(start, dso, MAP__FUNCTION); 689 map = map__new2(start, dso);
693 if (map == NULL) 690 if (map == NULL)
694 goto out; 691 goto out;
695 692
@@ -857,62 +854,44 @@ static int machine__get_running_kernel_start(struct machine *machine,
857static int 854static int
858__machine__create_kernel_maps(struct machine *machine, struct dso *kernel) 855__machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
859{ 856{
860 int type; 857 struct kmap *kmap;
858 struct map *map;
861 859
862 /* In case of renewal the kernel map, destroy previous one */ 860 /* In case of renewal the kernel map, destroy previous one */
863 machine__destroy_kernel_maps(machine); 861 machine__destroy_kernel_maps(machine);
864 862
865 for (type = 0; type < MAP__NR_TYPES; ++type) { 863 machine->vmlinux_map = map__new2(0, kernel);
866 struct kmap *kmap; 864 if (machine->vmlinux_map == NULL)
867 struct map *map; 865 return -1;
868
869 machine->vmlinux_maps[type] = map__new2(0, kernel, type);
870 if (machine->vmlinux_maps[type] == NULL)
871 return -1;
872 866
873 machine->vmlinux_maps[type]->map_ip = 867 machine->vmlinux_map->map_ip = machine->vmlinux_map->unmap_ip = identity__map_ip;
874 machine->vmlinux_maps[type]->unmap_ip = 868 map = machine__kernel_map(machine);
875 identity__map_ip; 869 kmap = map__kmap(map);
876 map = __machine__kernel_map(machine, type); 870 if (!kmap)
877 kmap = map__kmap(map); 871 return -1;
878 if (!kmap)
879 return -1;
880 872
881 kmap->kmaps = &machine->kmaps; 873 kmap->kmaps = &machine->kmaps;
882 map_groups__insert(&machine->kmaps, map); 874 map_groups__insert(&machine->kmaps, map);
883 }
884 875
885 return 0; 876 return 0;
886} 877}
887 878
888void machine__destroy_kernel_maps(struct machine *machine) 879void machine__destroy_kernel_maps(struct machine *machine)
889{ 880{
890 int type; 881 struct kmap *kmap;
891 882 struct map *map = machine__kernel_map(machine);
892 for (type = 0; type < MAP__NR_TYPES; ++type) {
893 struct kmap *kmap;
894 struct map *map = __machine__kernel_map(machine, type);
895
896 if (map == NULL)
897 continue;
898 883
899 kmap = map__kmap(map); 884 if (map == NULL)
900 map_groups__remove(&machine->kmaps, map); 885 return;
901 if (kmap && kmap->ref_reloc_sym) {
902 /*
903 * ref_reloc_sym is shared among all maps, so free just
904 * on one of them.
905 */
906 if (type == MAP__FUNCTION) {
907 zfree((char **)&kmap->ref_reloc_sym->name);
908 zfree(&kmap->ref_reloc_sym);
909 } else
910 kmap->ref_reloc_sym = NULL;
911 }
912 886
913 map__put(machine->vmlinux_maps[type]); 887 kmap = map__kmap(map);
914 machine->vmlinux_maps[type] = NULL; 888 map_groups__remove(&machine->kmaps, map);
889 if (kmap && kmap->ref_reloc_sym) {
890 zfree((char **)&kmap->ref_reloc_sym->name);
891 zfree(&kmap->ref_reloc_sym);
915 } 892 }
893
894 map__zput(machine->vmlinux_map);
916} 895}
917 896
918int machines__create_guest_kernel_maps(struct machines *machines) 897int machines__create_guest_kernel_maps(struct machines *machines)
@@ -989,32 +968,31 @@ int machines__create_kernel_maps(struct machines *machines, pid_t pid)
989 return machine__create_kernel_maps(machine); 968 return machine__create_kernel_maps(machine);
990} 969}
991 970
992int machine__load_kallsyms(struct machine *machine, const char *filename, 971int machine__load_kallsyms(struct machine *machine, const char *filename)
993 enum map_type type)
994{ 972{
995 struct map *map = machine__kernel_map(machine); 973 struct map *map = machine__kernel_map(machine);
996 int ret = __dso__load_kallsyms(map->dso, filename, map, true); 974 int ret = __dso__load_kallsyms(map->dso, filename, map, true);
997 975
998 if (ret > 0) { 976 if (ret > 0) {
999 dso__set_loaded(map->dso, type); 977 dso__set_loaded(map->dso);
1000 /* 978 /*
1001 * Since /proc/kallsyms will have multiple sessions for the 979 * Since /proc/kallsyms will have multiple sessions for the
1002 * kernel, with modules between them, fixup the end of all 980 * kernel, with modules between them, fixup the end of all
1003 * sections. 981 * sections.
1004 */ 982 */
1005 __map_groups__fixup_end(&machine->kmaps, type); 983 map_groups__fixup_end(&machine->kmaps);
1006 } 984 }
1007 985
1008 return ret; 986 return ret;
1009} 987}
1010 988
1011int machine__load_vmlinux_path(struct machine *machine, enum map_type type) 989int machine__load_vmlinux_path(struct machine *machine)
1012{ 990{
1013 struct map *map = machine__kernel_map(machine); 991 struct map *map = machine__kernel_map(machine);
1014 int ret = dso__load_vmlinux_path(map->dso, map); 992 int ret = dso__load_vmlinux_path(map->dso, map);
1015 993
1016 if (ret > 0) 994 if (ret > 0)
1017 dso__set_loaded(map->dso, type); 995 dso__set_loaded(map->dso);
1018 996
1019 return ret; 997 return ret;
1020} 998}
@@ -1055,10 +1033,9 @@ static bool is_kmod_dso(struct dso *dso)
1055static int map_groups__set_module_path(struct map_groups *mg, const char *path, 1033static int map_groups__set_module_path(struct map_groups *mg, const char *path,
1056 struct kmod_path *m) 1034 struct kmod_path *m)
1057{ 1035{
1058 struct map *map;
1059 char *long_name; 1036 char *long_name;
1037 struct map *map = map_groups__find_by_name(mg, m->name);
1060 1038
1061 map = map_groups__find_by_name(mg, MAP__FUNCTION, m->name);
1062 if (map == NULL) 1039 if (map == NULL)
1063 return 0; 1040 return 0;
1064 1041
@@ -1207,19 +1184,14 @@ static int machine__create_modules(struct machine *machine)
1207static void machine__set_kernel_mmap(struct machine *machine, 1184static void machine__set_kernel_mmap(struct machine *machine,
1208 u64 start, u64 end) 1185 u64 start, u64 end)
1209{ 1186{
1210 int i; 1187 machine->vmlinux_map->start = start;
1211 1188 machine->vmlinux_map->end = end;
1212 for (i = 0; i < MAP__NR_TYPES; i++) { 1189 /*
1213 machine->vmlinux_maps[i]->start = start; 1190 * Be a bit paranoid here, some perf.data file came with
1214 machine->vmlinux_maps[i]->end = end; 1191 * a zero sized synthesized MMAP event for the kernel.
1215 1192 */
1216 /* 1193 if (start == 0 && end == 0)
1217 * Be a bit paranoid here, some perf.data file came with 1194 machine->vmlinux_map->end = ~0ULL;
1218 * a zero sized synthesized MMAP event for the kernel.
1219 */
1220 if (start == 0 && end == 0)
1221 machine->vmlinux_maps[i]->end = ~0ULL;
1222 }
1223} 1195}
1224 1196
1225int machine__create_kernel_maps(struct machine *machine) 1197int machine__create_kernel_maps(struct machine *machine)
@@ -1249,7 +1221,7 @@ int machine__create_kernel_maps(struct machine *machine)
1249 1221
1250 if (!machine__get_running_kernel_start(machine, &name, &addr)) { 1222 if (!machine__get_running_kernel_start(machine, &name, &addr)) {
1251 if (name && 1223 if (name &&
1252 maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, addr)) { 1224 map__set_kallsyms_ref_reloc_sym(machine->vmlinux_map, name, addr)) {
1253 machine__destroy_kernel_maps(machine); 1225 machine__destroy_kernel_maps(machine);
1254 return -1; 1226 return -1;
1255 } 1227 }
@@ -1379,9 +1351,9 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
1379 * time /proc/sys/kernel/kptr_restrict was non zero. 1351 * time /proc/sys/kernel/kptr_restrict was non zero.
1380 */ 1352 */
1381 if (event->mmap.pgoff != 0) { 1353 if (event->mmap.pgoff != 0) {
1382 maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, 1354 map__set_kallsyms_ref_reloc_sym(machine->vmlinux_map,
1383 symbol_name, 1355 symbol_name,
1384 event->mmap.pgoff); 1356 event->mmap.pgoff);
1385 } 1357 }
1386 1358
1387 if (machine__is_default_guest(machine)) { 1359 if (machine__is_default_guest(machine)) {
@@ -1402,7 +1374,6 @@ int machine__process_mmap2_event(struct machine *machine,
1402{ 1374{
1403 struct thread *thread; 1375 struct thread *thread;
1404 struct map *map; 1376 struct map *map;
1405 enum map_type type;
1406 int ret = 0; 1377 int ret = 0;
1407 1378
1408 if (dump_trace) 1379 if (dump_trace)
@@ -1421,11 +1392,6 @@ int machine__process_mmap2_event(struct machine *machine,
1421 if (thread == NULL) 1392 if (thread == NULL)
1422 goto out_problem; 1393 goto out_problem;
1423 1394
1424 if (event->header.misc & PERF_RECORD_MISC_MMAP_DATA)
1425 type = MAP__VARIABLE;
1426 else
1427 type = MAP__FUNCTION;
1428
1429 map = map__new(machine, event->mmap2.start, 1395 map = map__new(machine, event->mmap2.start,
1430 event->mmap2.len, event->mmap2.pgoff, 1396 event->mmap2.len, event->mmap2.pgoff,
1431 event->mmap2.maj, 1397 event->mmap2.maj,
@@ -1433,7 +1399,7 @@ int machine__process_mmap2_event(struct machine *machine,
1433 event->mmap2.ino_generation, 1399 event->mmap2.ino_generation,
1434 event->mmap2.prot, 1400 event->mmap2.prot,
1435 event->mmap2.flags, 1401 event->mmap2.flags,
1436 event->mmap2.filename, type, thread); 1402 event->mmap2.filename, thread);
1437 1403
1438 if (map == NULL) 1404 if (map == NULL)
1439 goto out_problem_map; 1405 goto out_problem_map;
@@ -1460,7 +1426,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
1460{ 1426{
1461 struct thread *thread; 1427 struct thread *thread;
1462 struct map *map; 1428 struct map *map;
1463 enum map_type type; 1429 u32 prot = 0;
1464 int ret = 0; 1430 int ret = 0;
1465 1431
1466 if (dump_trace) 1432 if (dump_trace)
@@ -1479,16 +1445,14 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
1479 if (thread == NULL) 1445 if (thread == NULL)
1480 goto out_problem; 1446 goto out_problem;
1481 1447
1482 if (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) 1448 if (!(event->header.misc & PERF_RECORD_MISC_MMAP_DATA))
1483 type = MAP__VARIABLE; 1449 prot = PROT_EXEC;
1484 else
1485 type = MAP__FUNCTION;
1486 1450
1487 map = map__new(machine, event->mmap.start, 1451 map = map__new(machine, event->mmap.start,
1488 event->mmap.len, event->mmap.pgoff, 1452 event->mmap.len, event->mmap.pgoff,
1489 0, 0, 0, 0, 0, 0, 1453 0, 0, 0, 0, prot, 0,
1490 event->mmap.filename, 1454 event->mmap.filename,
1491 type, thread); 1455 thread);
1492 1456
1493 if (map == NULL) 1457 if (map == NULL)
1494 goto out_problem_map; 1458 goto out_problem_map;
@@ -1664,7 +1628,7 @@ static void ip__resolve_ams(struct thread *thread,
1664 * Thus, we have to try consecutively until we find a match 1628 * Thus, we have to try consecutively until we find a match
1665 * or else, the symbol is unknown 1629 * or else, the symbol is unknown
1666 */ 1630 */
1667 thread__find_cpumode_addr_location(thread, MAP__FUNCTION, ip, &al); 1631 thread__find_cpumode_addr_location(thread, ip, &al);
1668 1632
1669 ams->addr = ip; 1633 ams->addr = ip;
1670 ams->al_addr = al.addr; 1634 ams->al_addr = al.addr;
@@ -1681,15 +1645,7 @@ static void ip__resolve_data(struct thread *thread,
1681 1645
1682 memset(&al, 0, sizeof(al)); 1646 memset(&al, 0, sizeof(al));
1683 1647
1684 thread__find_addr_location(thread, m, MAP__VARIABLE, addr, &al); 1648 thread__find_symbol(thread, m, addr, &al);
1685 if (al.map == NULL) {
1686 /*
1687 * some shared data regions have execute bit set which puts
1688 * their mapping in the MAP__FUNCTION type array.
1689 * Check there as a fallback option before dropping the sample.
1690 */
1691 thread__find_addr_location(thread, m, MAP__FUNCTION, addr, &al);
1692 }
1693 1649
1694 ams->addr = addr; 1650 ams->addr = addr;
1695 ams->al_addr = al.addr; 1651 ams->al_addr = al.addr;
@@ -1758,8 +1714,7 @@ static int add_callchain_ip(struct thread *thread,
1758 al.filtered = 0; 1714 al.filtered = 0;
1759 al.sym = NULL; 1715 al.sym = NULL;
1760 if (!cpumode) { 1716 if (!cpumode) {
1761 thread__find_cpumode_addr_location(thread, MAP__FUNCTION, 1717 thread__find_cpumode_addr_location(thread, ip, &al);
1762 ip, &al);
1763 } else { 1718 } else {
1764 if (ip >= PERF_CONTEXT_MAX) { 1719 if (ip >= PERF_CONTEXT_MAX) {
1765 switch (ip) { 1720 switch (ip) {
@@ -1784,8 +1739,7 @@ static int add_callchain_ip(struct thread *thread,
1784 } 1739 }
1785 return 0; 1740 return 0;
1786 } 1741 }
1787 thread__find_addr_location(thread, *cpumode, MAP__FUNCTION, 1742 thread__find_symbol(thread, *cpumode, ip, &al);
1788 ip, &al);
1789 } 1743 }
1790 1744
1791 if (al.sym != NULL) { 1745 if (al.sym != NULL) {
@@ -2373,7 +2327,7 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch
2373{ 2327{
2374 struct machine *machine = vmachine; 2328 struct machine *machine = vmachine;
2375 struct map *map; 2329 struct map *map;
2376 struct symbol *sym = map_groups__find_symbol(&machine->kmaps, MAP__FUNCTION, *addrp, &map); 2330 struct symbol *sym = machine__find_kernel_symbol(machine, *addrp, &map);
2377 2331
2378 if (sym == NULL) 2332 if (sym == NULL)
2379 return NULL; 2333 return NULL;
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 66cc200ef86f..388fb4741c54 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -49,7 +49,7 @@ struct machine {
49 struct perf_env *env; 49 struct perf_env *env;
50 struct dsos dsos; 50 struct dsos dsos;
51 struct map_groups kmaps; 51 struct map_groups kmaps;
52 struct map *vmlinux_maps[MAP__NR_TYPES]; 52 struct map *vmlinux_map;
53 u64 kernel_start; 53 u64 kernel_start;
54 pid_t *current_tid; 54 pid_t *current_tid;
55 union { /* Tool specific area */ 55 union { /* Tool specific area */
@@ -64,16 +64,22 @@ static inline struct threads *machine__threads(struct machine *machine, pid_t ti
64 return &machine->threads[(unsigned int)tid % THREADS__TABLE_SIZE]; 64 return &machine->threads[(unsigned int)tid % THREADS__TABLE_SIZE];
65} 65}
66 66
67/*
68 * The main kernel (vmlinux) map
69 */
67static inline 70static inline
68struct map *__machine__kernel_map(struct machine *machine, enum map_type type) 71struct map *machine__kernel_map(struct machine *machine)
69{ 72{
70 return machine->vmlinux_maps[type]; 73 return machine->vmlinux_map;
71} 74}
72 75
76/*
77 * kernel (the one returned by machine__kernel_map()) plus kernel modules maps
78 */
73static inline 79static inline
74struct map *machine__kernel_map(struct machine *machine) 80struct maps *machine__kernel_maps(struct machine *machine)
75{ 81{
76 return __machine__kernel_map(machine, MAP__FUNCTION); 82 return &machine->kmaps.maps;
77} 83}
78 84
79int machine__get_kernel_start(struct machine *machine); 85int machine__get_kernel_start(struct machine *machine);
@@ -190,44 +196,27 @@ struct dso *machine__findnew_dso(struct machine *machine, const char *filename);
190size_t machine__fprintf(struct machine *machine, FILE *fp); 196size_t machine__fprintf(struct machine *machine, FILE *fp);
191 197
192static inline 198static inline
193struct symbol *machine__find_kernel_symbol(struct machine *machine, 199struct symbol *machine__find_kernel_symbol(struct machine *machine, u64 addr,
194 enum map_type type, u64 addr,
195 struct map **mapp) 200 struct map **mapp)
196{ 201{
197 return map_groups__find_symbol(&machine->kmaps, type, addr, mapp); 202 return map_groups__find_symbol(&machine->kmaps, addr, mapp);
198} 203}
199 204
200static inline 205static inline
201struct symbol *machine__find_kernel_symbol_by_name(struct machine *machine, 206struct symbol *machine__find_kernel_symbol_by_name(struct machine *machine,
202 enum map_type type, const char *name, 207 const char *name,
203 struct map **mapp) 208 struct map **mapp)
204{ 209{
205 return map_groups__find_symbol_by_name(&machine->kmaps, type, name, mapp); 210 return map_groups__find_symbol_by_name(&machine->kmaps, name, mapp);
206}
207
208static inline
209struct symbol *machine__find_kernel_function(struct machine *machine, u64 addr,
210 struct map **mapp)
211{
212 return machine__find_kernel_symbol(machine, MAP__FUNCTION, addr,
213 mapp);
214}
215
216static inline
217struct symbol *machine__find_kernel_function_by_name(struct machine *machine,
218 const char *name,
219 struct map **mapp)
220{
221 return map_groups__find_function_by_name(&machine->kmaps, name, mapp);
222} 211}
223 212
224struct map *machine__findnew_module_map(struct machine *machine, u64 start, 213struct map *machine__findnew_module_map(struct machine *machine, u64 start,
225 const char *filename); 214 const char *filename);
226int arch__fix_module_text_start(u64 *start, const char *name); 215int arch__fix_module_text_start(u64 *start, const char *name);
227 216
228int machine__load_kallsyms(struct machine *machine, const char *filename, 217int machine__load_kallsyms(struct machine *machine, const char *filename);
229 enum map_type type); 218
230int machine__load_vmlinux_path(struct machine *machine, enum map_type type); 219int machine__load_vmlinux_path(struct machine *machine);
231 220
232size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp, 221size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp,
233 bool (skip)(struct dso *dso, int parm), int parm); 222 bool (skip)(struct dso *dso, int parm), int parm);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 8fe57031e1a8..c8fe836e4c3c 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -22,11 +22,6 @@
22 22
23static void __maps__insert(struct maps *maps, struct map *map); 23static void __maps__insert(struct maps *maps, struct map *map);
24 24
25const char *map_type__name[MAP__NR_TYPES] = {
26 [MAP__FUNCTION] = "Functions",
27 [MAP__VARIABLE] = "Variables",
28};
29
30static inline int is_anon_memory(const char *filename, u32 flags) 25static inline int is_anon_memory(const char *filename, u32 flags)
31{ 26{
32 return flags & MAP_HUGETLB || 27 return flags & MAP_HUGETLB ||
@@ -129,10 +124,8 @@ static inline bool replace_android_lib(const char *filename, char *newfilename)
129 return false; 124 return false;
130} 125}
131 126
132void map__init(struct map *map, enum map_type type, 127void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso)
133 u64 start, u64 end, u64 pgoff, struct dso *dso)
134{ 128{
135 map->type = type;
136 map->start = start; 129 map->start = start;
137 map->end = end; 130 map->end = end;
138 map->pgoff = pgoff; 131 map->pgoff = pgoff;
@@ -149,7 +142,7 @@ void map__init(struct map *map, enum map_type type,
149struct map *map__new(struct machine *machine, u64 start, u64 len, 142struct map *map__new(struct machine *machine, u64 start, u64 len,
150 u64 pgoff, u32 d_maj, u32 d_min, u64 ino, 143 u64 pgoff, u32 d_maj, u32 d_min, u64 ino,
151 u64 ino_gen, u32 prot, u32 flags, char *filename, 144 u64 ino_gen, u32 prot, u32 flags, char *filename,
152 enum map_type type, struct thread *thread) 145 struct thread *thread)
153{ 146{
154 struct map *map = malloc(sizeof(*map)); 147 struct map *map = malloc(sizeof(*map));
155 struct nsinfo *nsi = NULL; 148 struct nsinfo *nsi = NULL;
@@ -173,7 +166,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
173 map->flags = flags; 166 map->flags = flags;
174 nsi = nsinfo__get(thread->nsinfo); 167 nsi = nsinfo__get(thread->nsinfo);
175 168
176 if ((anon || no_dso) && nsi && type == MAP__FUNCTION) { 169 if ((anon || no_dso) && nsi && (prot & PROT_EXEC)) {
177 snprintf(newfilename, sizeof(newfilename), 170 snprintf(newfilename, sizeof(newfilename),
178 "/tmp/perf-%d.map", nsi->pid); 171 "/tmp/perf-%d.map", nsi->pid);
179 filename = newfilename; 172 filename = newfilename;
@@ -203,7 +196,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
203 if (dso == NULL) 196 if (dso == NULL)
204 goto out_delete; 197 goto out_delete;
205 198
206 map__init(map, type, start, start + len, pgoff, dso); 199 map__init(map, start, start + len, pgoff, dso);
207 200
208 if (anon || no_dso) { 201 if (anon || no_dso) {
209 map->map_ip = map->unmap_ip = identity__map_ip; 202 map->map_ip = map->unmap_ip = identity__map_ip;
@@ -213,8 +206,8 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
213 * functions still return NULL, and we avoid the 206 * functions still return NULL, and we avoid the
214 * unnecessary map__load warning. 207 * unnecessary map__load warning.
215 */ 208 */
216 if (type != MAP__FUNCTION) 209 if (!(prot & PROT_EXEC))
217 dso__set_loaded(dso, map->type); 210 dso__set_loaded(dso);
218 } 211 }
219 dso->nsinfo = nsi; 212 dso->nsinfo = nsi;
220 dso__put(dso); 213 dso__put(dso);
@@ -231,7 +224,7 @@ out_delete:
231 * they are loaded) and for vmlinux, where only after we load all the 224 * they are loaded) and for vmlinux, where only after we load all the
232 * symbols we'll know where it starts and ends. 225 * symbols we'll know where it starts and ends.
233 */ 226 */
234struct map *map__new2(u64 start, struct dso *dso, enum map_type type) 227struct map *map__new2(u64 start, struct dso *dso)
235{ 228{
236 struct map *map = calloc(1, (sizeof(*map) + 229 struct map *map = calloc(1, (sizeof(*map) +
237 (dso->kernel ? sizeof(struct kmap) : 0))); 230 (dso->kernel ? sizeof(struct kmap) : 0)));
@@ -239,7 +232,7 @@ struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
239 /* 232 /*
240 * ->end will be filled after we load all the symbols 233 * ->end will be filled after we load all the symbols
241 */ 234 */
242 map__init(map, type, start, 0, 0, dso); 235 map__init(map, start, 0, 0, dso);
243 } 236 }
244 237
245 return map; 238 return map;
@@ -256,7 +249,12 @@ struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
256 */ 249 */
257bool __map__is_kernel(const struct map *map) 250bool __map__is_kernel(const struct map *map)
258{ 251{
259 return __machine__kernel_map(map->groups->machine, map->type) == map; 252 return machine__kernel_map(map->groups->machine) == map;
253}
254
255bool map__has_symbols(const struct map *map)
256{
257 return dso__has_symbols(map->dso);
260} 258}
261 259
262static void map__exit(struct map *map) 260static void map__exit(struct map *map)
@@ -279,7 +277,7 @@ void map__put(struct map *map)
279 277
280void map__fixup_start(struct map *map) 278void map__fixup_start(struct map *map)
281{ 279{
282 struct rb_root *symbols = &map->dso->symbols[map->type]; 280 struct rb_root *symbols = &map->dso->symbols;
283 struct rb_node *nd = rb_first(symbols); 281 struct rb_node *nd = rb_first(symbols);
284 if (nd != NULL) { 282 if (nd != NULL) {
285 struct symbol *sym = rb_entry(nd, struct symbol, rb_node); 283 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
@@ -289,7 +287,7 @@ void map__fixup_start(struct map *map)
289 287
290void map__fixup_end(struct map *map) 288void map__fixup_end(struct map *map)
291{ 289{
292 struct rb_root *symbols = &map->dso->symbols[map->type]; 290 struct rb_root *symbols = &map->dso->symbols;
293 struct rb_node *nd = rb_last(symbols); 291 struct rb_node *nd = rb_last(symbols);
294 if (nd != NULL) { 292 if (nd != NULL) {
295 struct symbol *sym = rb_entry(nd, struct symbol, rb_node); 293 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
@@ -304,7 +302,7 @@ int map__load(struct map *map)
304 const char *name = map->dso->long_name; 302 const char *name = map->dso->long_name;
305 int nr; 303 int nr;
306 304
307 if (dso__loaded(map->dso, map->type)) 305 if (dso__loaded(map->dso))
308 return 0; 306 return 0;
309 307
310 nr = dso__load(map->dso, map); 308 nr = dso__load(map->dso, map);
@@ -348,7 +346,7 @@ struct symbol *map__find_symbol(struct map *map, u64 addr)
348 if (map__load(map) < 0) 346 if (map__load(map) < 0)
349 return NULL; 347 return NULL;
350 348
351 return dso__find_symbol(map->dso, map->type, addr); 349 return dso__find_symbol(map->dso, addr);
352} 350}
353 351
354struct symbol *map__find_symbol_by_name(struct map *map, const char *name) 352struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
@@ -356,10 +354,10 @@ struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
356 if (map__load(map) < 0) 354 if (map__load(map) < 0)
357 return NULL; 355 return NULL;
358 356
359 if (!dso__sorted_by_name(map->dso, map->type)) 357 if (!dso__sorted_by_name(map->dso))
360 dso__sort_by_name(map->dso, map->type); 358 dso__sort_by_name(map->dso);
361 359
362 return dso__find_symbol_by_name(map->dso, map->type, name); 360 return dso__find_symbol_by_name(map->dso, name);
363} 361}
364 362
365struct map *map__clone(struct map *from) 363struct map *map__clone(struct map *from)
@@ -494,10 +492,7 @@ static void maps__init(struct maps *maps)
494 492
495void map_groups__init(struct map_groups *mg, struct machine *machine) 493void map_groups__init(struct map_groups *mg, struct machine *machine)
496{ 494{
497 int i; 495 maps__init(&mg->maps);
498 for (i = 0; i < MAP__NR_TYPES; ++i) {
499 maps__init(&mg->maps[i]);
500 }
501 mg->machine = machine; 496 mg->machine = machine;
502 refcount_set(&mg->refcnt, 1); 497 refcount_set(&mg->refcnt, 1);
503} 498}
@@ -525,22 +520,12 @@ static void maps__exit(struct maps *maps)
525 520
526void map_groups__exit(struct map_groups *mg) 521void map_groups__exit(struct map_groups *mg)
527{ 522{
528 int i; 523 maps__exit(&mg->maps);
529
530 for (i = 0; i < MAP__NR_TYPES; ++i)
531 maps__exit(&mg->maps[i]);
532} 524}
533 525
534bool map_groups__empty(struct map_groups *mg) 526bool map_groups__empty(struct map_groups *mg)
535{ 527{
536 int i; 528 return !maps__first(&mg->maps);
537
538 for (i = 0; i < MAP__NR_TYPES; ++i) {
539 if (maps__first(&mg->maps[i]))
540 return false;
541 }
542
543 return true;
544} 529}
545 530
546struct map_groups *map_groups__new(struct machine *machine) 531struct map_groups *map_groups__new(struct machine *machine)
@@ -566,10 +551,9 @@ void map_groups__put(struct map_groups *mg)
566} 551}
567 552
568struct symbol *map_groups__find_symbol(struct map_groups *mg, 553struct symbol *map_groups__find_symbol(struct map_groups *mg,
569 enum map_type type, u64 addr, 554 u64 addr, struct map **mapp)
570 struct map **mapp)
571{ 555{
572 struct map *map = map_groups__find(mg, type, addr); 556 struct map *map = map_groups__find(mg, addr);
573 557
574 /* Ensure map is loaded before using map->map_ip */ 558 /* Ensure map is loaded before using map->map_ip */
575 if (map != NULL && map__load(map) >= 0) { 559 if (map != NULL && map__load(map) >= 0) {
@@ -608,13 +592,10 @@ out:
608} 592}
609 593
610struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, 594struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
611 enum map_type type,
612 const char *name, 595 const char *name,
613 struct map **mapp) 596 struct map **mapp)
614{ 597{
615 struct symbol *sym = maps__find_symbol_by_name(&mg->maps[type], name, mapp); 598 return maps__find_symbol_by_name(&mg->maps, name, mapp);
616
617 return sym;
618} 599}
619 600
620int map_groups__find_ams(struct addr_map_symbol *ams) 601int map_groups__find_ams(struct addr_map_symbol *ams)
@@ -622,8 +603,7 @@ int map_groups__find_ams(struct addr_map_symbol *ams)
622 if (ams->addr < ams->map->start || ams->addr >= ams->map->end) { 603 if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {
623 if (ams->map->groups == NULL) 604 if (ams->map->groups == NULL)
624 return -1; 605 return -1;
625 ams->map = map_groups__find(ams->map->groups, ams->map->type, 606 ams->map = map_groups__find(ams->map->groups, ams->addr);
626 ams->addr);
627 if (ams->map == NULL) 607 if (ams->map == NULL)
628 return -1; 608 return -1;
629 } 609 }
@@ -646,7 +626,7 @@ static size_t maps__fprintf(struct maps *maps, FILE *fp)
646 printed += fprintf(fp, "Map:"); 626 printed += fprintf(fp, "Map:");
647 printed += map__fprintf(pos, fp); 627 printed += map__fprintf(pos, fp);
648 if (verbose > 2) { 628 if (verbose > 2) {
649 printed += dso__fprintf(pos->dso, pos->type, fp); 629 printed += dso__fprintf(pos->dso, fp);
650 printed += fprintf(fp, "--\n"); 630 printed += fprintf(fp, "--\n");
651 } 631 }
652 } 632 }
@@ -656,24 +636,14 @@ static size_t maps__fprintf(struct maps *maps, FILE *fp)
656 return printed; 636 return printed;
657} 637}
658 638
659size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
660 FILE *fp)
661{
662 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
663 return printed += maps__fprintf(&mg->maps[type], fp);
664}
665
666size_t map_groups__fprintf(struct map_groups *mg, FILE *fp) 639size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
667{ 640{
668 size_t printed = 0, i; 641 return maps__fprintf(&mg->maps, fp);
669 for (i = 0; i < MAP__NR_TYPES; ++i)
670 printed += __map_groups__fprintf_maps(mg, i, fp);
671 return printed;
672} 642}
673 643
674static void __map_groups__insert(struct map_groups *mg, struct map *map) 644static void __map_groups__insert(struct map_groups *mg, struct map *map)
675{ 645{
676 __maps__insert(&mg->maps[map->type], map); 646 __maps__insert(&mg->maps, map);
677 map->groups = mg; 647 map->groups = mg;
678} 648}
679 649
@@ -758,19 +728,18 @@ out:
758int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, 728int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
759 FILE *fp) 729 FILE *fp)
760{ 730{
761 return maps__fixup_overlappings(&mg->maps[map->type], map, fp); 731 return maps__fixup_overlappings(&mg->maps, map, fp);
762} 732}
763 733
764/* 734/*
765 * XXX This should not really _copy_ te maps, but refcount them. 735 * XXX This should not really _copy_ te maps, but refcount them.
766 */ 736 */
767int map_groups__clone(struct thread *thread, 737int map_groups__clone(struct thread *thread, struct map_groups *parent)
768 struct map_groups *parent, enum map_type type)
769{ 738{
770 struct map_groups *mg = thread->mg; 739 struct map_groups *mg = thread->mg;
771 int err = -ENOMEM; 740 int err = -ENOMEM;
772 struct map *map; 741 struct map *map;
773 struct maps *maps = &parent->maps[type]; 742 struct maps *maps = &parent->maps;
774 743
775 down_read(&maps->lock); 744 down_read(&maps->lock);
776 745
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 0e9bbe01b0ab..f1afe1ab6ff7 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -12,15 +12,6 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include "rwsem.h" 13#include "rwsem.h"
14 14
15enum map_type {
16 MAP__FUNCTION = 0,
17 MAP__VARIABLE,
18};
19
20#define MAP__NR_TYPES (MAP__VARIABLE + 1)
21
22extern const char *map_type__name[MAP__NR_TYPES];
23
24struct dso; 15struct dso;
25struct ip_callchain; 16struct ip_callchain;
26struct ref_reloc_sym; 17struct ref_reloc_sym;
@@ -35,7 +26,6 @@ struct map {
35 }; 26 };
36 u64 start; 27 u64 start;
37 u64 end; 28 u64 end;
38 u8 /* enum map_type */ type;
39 bool erange_warned; 29 bool erange_warned;
40 u32 priv; 30 u32 priv;
41 u32 prot; 31 u32 prot;
@@ -67,7 +57,7 @@ struct maps {
67}; 57};
68 58
69struct map_groups { 59struct map_groups {
70 struct maps maps[MAP__NR_TYPES]; 60 struct maps maps;
71 struct machine *machine; 61 struct machine *machine;
72 refcount_t refcnt; 62 refcount_t refcnt;
73}; 63};
@@ -125,7 +115,7 @@ struct thread;
125 * Note: caller must ensure map->dso is not NULL (map is loaded). 115 * Note: caller must ensure map->dso is not NULL (map is loaded).
126 */ 116 */
127#define map__for_each_symbol(map, pos, n) \ 117#define map__for_each_symbol(map, pos, n) \
128 dso__for_each_symbol(map->dso, pos, n, map->type) 118 dso__for_each_symbol(map->dso, pos, n)
129 119
130/* map__for_each_symbol_with_name - iterate over the symbols in the given map 120/* map__for_each_symbol_with_name - iterate over the symbols in the given map
131 * that have the given name 121 * that have the given name
@@ -144,13 +134,13 @@ struct thread;
144#define map__for_each_symbol_by_name(map, sym_name, pos) \ 134#define map__for_each_symbol_by_name(map, sym_name, pos) \
145 __map__for_each_symbol_by_name(map, sym_name, (pos)) 135 __map__for_each_symbol_by_name(map, sym_name, (pos))
146 136
147void map__init(struct map *map, enum map_type type, 137void map__init(struct map *map,
148 u64 start, u64 end, u64 pgoff, struct dso *dso); 138 u64 start, u64 end, u64 pgoff, struct dso *dso);
149struct map *map__new(struct machine *machine, u64 start, u64 len, 139struct map *map__new(struct machine *machine, u64 start, u64 len,
150 u64 pgoff, u32 d_maj, u32 d_min, u64 ino, 140 u64 pgoff, u32 d_maj, u32 d_min, u64 ino,
151 u64 ino_gen, u32 prot, u32 flags, 141 u64 ino_gen, u32 prot, u32 flags,
152 char *filename, enum map_type type, struct thread *thread); 142 char *filename, struct thread *thread);
153struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 143struct map *map__new2(u64 start, struct dso *dso);
154void map__delete(struct map *map); 144void map__delete(struct map *map);
155struct map *map__clone(struct map *map); 145struct map *map__clone(struct map *map);
156 146
@@ -185,8 +175,6 @@ void map__fixup_end(struct map *map);
185 175
186void map__reloc_vmlinux(struct map *map); 176void map__reloc_vmlinux(struct map *map);
187 177
188size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
189 FILE *fp);
190void maps__insert(struct maps *maps, struct map *map); 178void maps__insert(struct maps *maps, struct map *map);
191void maps__remove(struct maps *maps, struct map *map); 179void maps__remove(struct maps *maps, struct map *map);
192struct map *maps__find(struct maps *maps, u64 addr); 180struct map *maps__find(struct maps *maps, u64 addr);
@@ -197,34 +185,29 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
197void map_groups__init(struct map_groups *mg, struct machine *machine); 185void map_groups__init(struct map_groups *mg, struct machine *machine);
198void map_groups__exit(struct map_groups *mg); 186void map_groups__exit(struct map_groups *mg);
199int map_groups__clone(struct thread *thread, 187int map_groups__clone(struct thread *thread,
200 struct map_groups *parent, enum map_type type); 188 struct map_groups *parent);
201size_t map_groups__fprintf(struct map_groups *mg, FILE *fp); 189size_t map_groups__fprintf(struct map_groups *mg, FILE *fp);
202 190
203int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name, 191int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name,
204 u64 addr); 192 u64 addr);
205 193
206static inline void map_groups__insert(struct map_groups *mg, struct map *map) 194static inline void map_groups__insert(struct map_groups *mg, struct map *map)
207{ 195{
208 maps__insert(&mg->maps[map->type], map); 196 maps__insert(&mg->maps, map);
209 map->groups = mg; 197 map->groups = mg;
210} 198}
211 199
212static inline void map_groups__remove(struct map_groups *mg, struct map *map) 200static inline void map_groups__remove(struct map_groups *mg, struct map *map)
213{ 201{
214 maps__remove(&mg->maps[map->type], map); 202 maps__remove(&mg->maps, map);
215} 203}
216 204
217static inline struct map *map_groups__find(struct map_groups *mg, 205static inline struct map *map_groups__find(struct map_groups *mg, u64 addr)
218 enum map_type type, u64 addr)
219{ 206{
220 return maps__find(&mg->maps[type], addr); 207 return maps__find(&mg->maps, addr);
221} 208}
222 209
223static inline struct map *map_groups__first(struct map_groups *mg, 210struct map *map_groups__first(struct map_groups *mg);
224 enum map_type type)
225{
226 return maps__first(&mg->maps[type]);
227}
228 211
229static inline struct map *map_groups__next(struct map *map) 212static inline struct map *map_groups__next(struct map *map)
230{ 213{
@@ -232,11 +215,9 @@ static inline struct map *map_groups__next(struct map *map)
232} 215}
233 216
234struct symbol *map_groups__find_symbol(struct map_groups *mg, 217struct symbol *map_groups__find_symbol(struct map_groups *mg,
235 enum map_type type, u64 addr, 218 u64 addr, struct map **mapp);
236 struct map **mapp);
237 219
238struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, 220struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
239 enum map_type type,
240 const char *name, 221 const char *name,
241 struct map **mapp); 222 struct map **mapp);
242 223
@@ -244,18 +225,10 @@ struct addr_map_symbol;
244 225
245int map_groups__find_ams(struct addr_map_symbol *ams); 226int map_groups__find_ams(struct addr_map_symbol *ams);
246 227
247static inline
248struct symbol *map_groups__find_function_by_name(struct map_groups *mg,
249 const char *name, struct map **mapp)
250{
251 return map_groups__find_symbol_by_name(mg, MAP__FUNCTION, name, mapp);
252}
253
254int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, 228int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
255 FILE *fp); 229 FILE *fp);
256 230
257struct map *map_groups__find_by_name(struct map_groups *mg, 231struct map *map_groups__find_by_name(struct map_groups *mg, const char *name);
258 enum map_type type, const char *name);
259 232
260bool __map__is_kernel(const struct map *map); 233bool __map__is_kernel(const struct map *map);
261 234
@@ -264,4 +237,6 @@ static inline bool __map__is_kmodule(const struct map *map)
264 return !__map__is_kernel(map); 237 return !__map__is_kernel(map);
265} 238}
266 239
240bool map__has_symbols(const struct map *map);
241
267#endif /* __PERF_MAP_H */ 242#endif /* __PERF_MAP_H */
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index e1dbc9821617..3094f11e7d81 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -111,17 +111,6 @@ void exit_probe_symbol_maps(void)
111 symbol__exit(); 111 symbol__exit();
112} 112}
113 113
114static struct symbol *__find_kernel_function_by_name(const char *name,
115 struct map **mapp)
116{
117 return machine__find_kernel_function_by_name(host_machine, name, mapp);
118}
119
120static struct symbol *__find_kernel_function(u64 addr, struct map **mapp)
121{
122 return machine__find_kernel_function(host_machine, addr, mapp);
123}
124
125static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void) 114static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void)
126{ 115{
127 /* kmap->ref_reloc_sym should be set if host_machine is initialized */ 116 /* kmap->ref_reloc_sym should be set if host_machine is initialized */
@@ -149,7 +138,7 @@ static int kernel_get_symbol_address_by_name(const char *name, u64 *addr,
149 if (reloc_sym && strcmp(name, reloc_sym->name) == 0) 138 if (reloc_sym && strcmp(name, reloc_sym->name) == 0)
150 *addr = (reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr; 139 *addr = (reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr;
151 else { 140 else {
152 sym = __find_kernel_function_by_name(name, &map); 141 sym = machine__find_kernel_symbol_by_name(host_machine, name, &map);
153 if (!sym) 142 if (!sym)
154 return -ENOENT; 143 return -ENOENT;
155 *addr = map->unmap_ip(map, sym->start) - 144 *addr = map->unmap_ip(map, sym->start) -
@@ -161,8 +150,7 @@ static int kernel_get_symbol_address_by_name(const char *name, u64 *addr,
161 150
162static struct map *kernel_get_module_map(const char *module) 151static struct map *kernel_get_module_map(const char *module)
163{ 152{
164 struct map_groups *grp = &host_machine->kmaps; 153 struct maps *maps = machine__kernel_maps(host_machine);
165 struct maps *maps = &grp->maps[MAP__FUNCTION];
166 struct map *pos; 154 struct map *pos;
167 155
168 /* A file path -- this is an offline module */ 156 /* A file path -- this is an offline module */
@@ -341,7 +329,7 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso)
341 char module_name[128]; 329 char module_name[128];
342 330
343 snprintf(module_name, sizeof(module_name), "[%s]", module); 331 snprintf(module_name, sizeof(module_name), "[%s]", module);
344 map = map_groups__find_by_name(&host_machine->kmaps, MAP__FUNCTION, module_name); 332 map = map_groups__find_by_name(&host_machine->kmaps, module_name);
345 if (map) { 333 if (map) {
346 dso = map->dso; 334 dso = map->dso;
347 goto found; 335 goto found;
@@ -2098,7 +2086,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
2098 } 2086 }
2099 if (addr) { 2087 if (addr) {
2100 addr += tp->offset; 2088 addr += tp->offset;
2101 sym = __find_kernel_function(addr, &map); 2089 sym = machine__find_kernel_symbol(host_machine, addr, &map);
2102 } 2090 }
2103 } 2091 }
2104 2092
@@ -3504,19 +3492,18 @@ int show_available_funcs(const char *target, struct nsinfo *nsi,
3504 (target) ? : "kernel"); 3492 (target) ? : "kernel");
3505 goto end; 3493 goto end;
3506 } 3494 }
3507 if (!dso__sorted_by_name(map->dso, map->type)) 3495 if (!dso__sorted_by_name(map->dso))
3508 dso__sort_by_name(map->dso, map->type); 3496 dso__sort_by_name(map->dso);
3509 3497
3510 /* Show all (filtered) symbols */ 3498 /* Show all (filtered) symbols */
3511 setup_pager(); 3499 setup_pager();
3512 3500
3513 for (nd = rb_first(&map->dso->symbol_names[map->type]); nd; nd = rb_next(nd)) { 3501 for (nd = rb_first(&map->dso->symbol_names); nd; nd = rb_next(nd)) {
3514 struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); 3502 struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
3515 3503
3516 if (strfilter__compare(_filter, pos->sym.name)) 3504 if (strfilter__compare(_filter, pos->sym.name))
3517 printf("%s\n", pos->sym.name); 3505 printf("%s\n", pos->sym.name);
3518 } 3506 }
3519
3520end: 3507end:
3521 map__put(map); 3508 map__put(map);
3522 exit_probe_symbol_maps(); 3509 exit_probe_symbol_maps();
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index f4a7a437ee87..b998bb475589 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1973,12 +1973,11 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg)
1973 return false; 1973 return false;
1974} 1974}
1975 1975
1976int maps__set_kallsyms_ref_reloc_sym(struct map **maps, 1976int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, u64 addr)
1977 const char *symbol_name, u64 addr)
1978{ 1977{
1979 char *bracket; 1978 char *bracket;
1980 int i;
1981 struct ref_reloc_sym *ref; 1979 struct ref_reloc_sym *ref;
1980 struct kmap *kmap;
1982 1981
1983 ref = zalloc(sizeof(struct ref_reloc_sym)); 1982 ref = zalloc(sizeof(struct ref_reloc_sym));
1984 if (ref == NULL) 1983 if (ref == NULL)
@@ -1996,13 +1995,9 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
1996 1995
1997 ref->addr = addr; 1996 ref->addr = addr;
1998 1997
1999 for (i = 0; i < MAP__NR_TYPES; ++i) { 1998 kmap = map__kmap(map);
2000 struct kmap *kmap = map__kmap(maps[i]); 1999 if (kmap)
2001
2002 if (!kmap)
2003 continue;
2004 kmap->ref_reloc_sym = ref; 2000 kmap->ref_reloc_sym = ref;
2005 }
2006 2001
2007 return 0; 2002 return 0;
2008} 2003}
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 26a68dfd8a4f..e65903a695a6 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -2,7 +2,7 @@
2#include <errno.h> 2#include <errno.h>
3#include <inttypes.h> 3#include <inttypes.h>
4#include <regex.h> 4#include <regex.h>
5#include <sys/mman.h> 5#include <linux/mman.h>
6#include "sort.h" 6#include "sort.h"
7#include "hist.h" 7#include "hist.h"
8#include "comm.h" 8#include "comm.h"
@@ -282,7 +282,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
282 282
283 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level); 283 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level);
284 if (sym && map) { 284 if (sym && map) {
285 if (map->type == MAP__VARIABLE) { 285 if (sym->type == STT_OBJECT) {
286 ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name); 286 ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
287 ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx", 287 ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
288 ip - map->unmap_ip(map, sym->start)); 288 ip - map->unmap_ip(map, sym->start));
@@ -1211,7 +1211,7 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf,
1211 1211
1212 /* print [s] for shared data mmaps */ 1212 /* print [s] for shared data mmaps */
1213 if ((he->cpumode != PERF_RECORD_MISC_KERNEL) && 1213 if ((he->cpumode != PERF_RECORD_MISC_KERNEL) &&
1214 map && (map->type == MAP__VARIABLE) && 1214 map && !(map->prot & PROT_EXEC) &&
1215 (map->flags & MAP_SHARED) && 1215 (map->flags & MAP_SHARED) &&
1216 (map->maj || map->min || map->ino || 1216 (map->maj || map->min || map->ino ||
1217 map->ino_generation)) 1217 map->ino_generation))
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index 3c21fd059b64..09d6746e6ec8 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -103,6 +103,7 @@ static struct symbol *new_inline_sym(struct dso *dso,
103 inline_sym = symbol__new(base_sym ? base_sym->start : 0, 103 inline_sym = symbol__new(base_sym ? base_sym->start : 0,
104 base_sym ? base_sym->end : 0, 104 base_sym ? base_sym->end : 0,
105 base_sym ? base_sym->binding : 0, 105 base_sym ? base_sym->binding : 0,
106 base_sym ? base_sym->type : 0,
106 funcname); 107 funcname);
107 if (inline_sym) 108 if (inline_sym)
108 inline_sym->inlined = 1; 109 inline_sym->inlined = 1;
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 8f56ba4fd258..36efb986f7fc 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -7,8 +7,7 @@
7#include "xyarray.h" 7#include "xyarray.h"
8#include "rblist.h" 8#include "rblist.h"
9 9
10struct stats 10struct stats {
11{
12 double n, mean, M2; 11 double n, mean, M2;
13 u64 max, min; 12 u64 max, min;
14}; 13};
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 2de770511e70..48943b834f11 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -114,16 +114,9 @@ static inline int elf_sym__is_label(const GElf_Sym *sym)
114 sym->st_shndx != SHN_ABS; 114 sym->st_shndx != SHN_ABS;
115} 115}
116 116
117static bool elf_sym__is_a(GElf_Sym *sym, enum map_type type) 117static bool elf_sym__filter(GElf_Sym *sym)
118{ 118{
119 switch (type) { 119 return elf_sym__is_function(sym) || elf_sym__is_object(sym);
120 case MAP__FUNCTION:
121 return elf_sym__is_function(sym);
122 case MAP__VARIABLE:
123 return elf_sym__is_object(sym);
124 default:
125 return false;
126 }
127} 120}
128 121
129static inline const char *elf_sym__name(const GElf_Sym *sym, 122static inline const char *elf_sym__name(const GElf_Sym *sym,
@@ -150,17 +143,10 @@ static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
150 return strstr(elf_sec__name(shdr, secstrs), "data") != NULL; 143 return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
151} 144}
152 145
153static bool elf_sec__is_a(GElf_Shdr *shdr, Elf_Data *secstrs, 146static bool elf_sec__filter(GElf_Shdr *shdr, Elf_Data *secstrs)
154 enum map_type type)
155{ 147{
156 switch (type) { 148 return elf_sec__is_text(shdr, secstrs) ||
157 case MAP__FUNCTION: 149 elf_sec__is_data(shdr, secstrs);
158 return elf_sec__is_text(shdr, secstrs);
159 case MAP__VARIABLE:
160 return elf_sec__is_data(shdr, secstrs);
161 default:
162 return false;
163 }
164} 150}
165 151
166static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr) 152static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
@@ -256,7 +242,7 @@ static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name)
256 * And always look at the original dso, not at debuginfo packages, that 242 * And always look at the original dso, not at debuginfo packages, that
257 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). 243 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
258 */ 244 */
259int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *map) 245int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss)
260{ 246{
261 uint32_t nr_rel_entries, idx; 247 uint32_t nr_rel_entries, idx;
262 GElf_Sym sym; 248 GElf_Sym sym;
@@ -364,12 +350,12 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *
364 free(demangled); 350 free(demangled);
365 351
366 f = symbol__new(plt_offset, plt_entry_size, 352 f = symbol__new(plt_offset, plt_entry_size,
367 STB_GLOBAL, sympltname); 353 STB_GLOBAL, STT_FUNC, sympltname);
368 if (!f) 354 if (!f)
369 goto out_elf_end; 355 goto out_elf_end;
370 356
371 plt_offset += plt_entry_size; 357 plt_offset += plt_entry_size;
372 symbols__insert(&dso->symbols[map->type], f); 358 symbols__insert(&dso->symbols, f);
373 ++nr; 359 ++nr;
374 } 360 }
375 } else if (shdr_rel_plt.sh_type == SHT_REL) { 361 } else if (shdr_rel_plt.sh_type == SHT_REL) {
@@ -390,12 +376,12 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *
390 free(demangled); 376 free(demangled);
391 377
392 f = symbol__new(plt_offset, plt_entry_size, 378 f = symbol__new(plt_offset, plt_entry_size,
393 STB_GLOBAL, sympltname); 379 STB_GLOBAL, STT_FUNC, sympltname);
394 if (!f) 380 if (!f)
395 goto out_elf_end; 381 goto out_elf_end;
396 382
397 plt_offset += plt_entry_size; 383 plt_offset += plt_entry_size;
398 symbols__insert(&dso->symbols[map->type], f); 384 symbols__insert(&dso->symbols, f);
399 ++nr; 385 ++nr;
400 } 386 }
401 } 387 }
@@ -811,6 +797,110 @@ static u64 ref_reloc(struct kmap *kmap)
811void __weak arch__sym_update(struct symbol *s __maybe_unused, 797void __weak arch__sym_update(struct symbol *s __maybe_unused,
812 GElf_Sym *sym __maybe_unused) { } 798 GElf_Sym *sym __maybe_unused) { }
813 799
800static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
801 GElf_Sym *sym, GElf_Shdr *shdr,
802 struct map_groups *kmaps, struct kmap *kmap,
803 struct dso **curr_dsop, struct map **curr_mapp,
804 const char *section_name,
805 bool adjust_kernel_syms, bool kmodule, bool *remap_kernel)
806{
807 struct dso *curr_dso = *curr_dsop;
808 struct map *curr_map;
809 char dso_name[PATH_MAX];
810
811 /* Adjust symbol to map to file offset */
812 if (adjust_kernel_syms)
813 sym->st_value -= shdr->sh_addr - shdr->sh_offset;
814
815 if (strcmp(section_name, (curr_dso->short_name + dso->short_name_len)) == 0)
816 return 0;
817
818 if (strcmp(section_name, ".text") == 0) {
819 /*
820 * The initial kernel mapping is based on
821 * kallsyms and identity maps. Overwrite it to
822 * map to the kernel dso.
823 */
824 if (*remap_kernel && dso->kernel) {
825 *remap_kernel = false;
826 map->start = shdr->sh_addr + ref_reloc(kmap);
827 map->end = map->start + shdr->sh_size;
828 map->pgoff = shdr->sh_offset;
829 map->map_ip = map__map_ip;
830 map->unmap_ip = map__unmap_ip;
831 /* Ensure maps are correctly ordered */
832 if (kmaps) {
833 map__get(map);
834 map_groups__remove(kmaps, map);
835 map_groups__insert(kmaps, map);
836 map__put(map);
837 }
838 }
839
840 /*
841 * The initial module mapping is based on
842 * /proc/modules mapped to offset zero.
843 * Overwrite it to map to the module dso.
844 */
845 if (*remap_kernel && kmodule) {
846 *remap_kernel = false;
847 map->pgoff = shdr->sh_offset;
848 }
849
850 *curr_mapp = map;
851 *curr_dsop = dso;
852 return 0;
853 }
854
855 if (!kmap)
856 return 0;
857
858 snprintf(dso_name, sizeof(dso_name), "%s%s", dso->short_name, section_name);
859
860 curr_map = map_groups__find_by_name(kmaps, dso_name);
861 if (curr_map == NULL) {
862 u64 start = sym->st_value;
863
864 if (kmodule)
865 start += map->start + shdr->sh_offset;
866
867 curr_dso = dso__new(dso_name);
868 if (curr_dso == NULL)
869 return -1;
870 curr_dso->kernel = dso->kernel;
871 curr_dso->long_name = dso->long_name;
872 curr_dso->long_name_len = dso->long_name_len;
873 curr_map = map__new2(start, curr_dso);
874 dso__put(curr_dso);
875 if (curr_map == NULL)
876 return -1;
877
878 if (adjust_kernel_syms) {
879 curr_map->start = shdr->sh_addr + ref_reloc(kmap);
880 curr_map->end = curr_map->start + shdr->sh_size;
881 curr_map->pgoff = shdr->sh_offset;
882 } else {
883 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
884 }
885 curr_dso->symtab_type = dso->symtab_type;
886 map_groups__insert(kmaps, curr_map);
887 /*
888 * Add it before we drop the referece to curr_map, i.e. while
889 * we still are sure to have a reference to this DSO via
890 * *curr_map->dso.
891 */
892 dsos__add(&map->groups->machine->dsos, curr_dso);
893 /* kmaps already got it */
894 map__put(curr_map);
895 dso__set_loaded(curr_dso);
896 *curr_mapp = curr_map;
897 *curr_dsop = curr_dso;
898 } else
899 *curr_dsop = curr_map->dso;
900
901 return 0;
902}
903
814int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, 904int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
815 struct symsrc *runtime_ss, int kmodule) 905 struct symsrc *runtime_ss, int kmodule)
816{ 906{
@@ -844,7 +934,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
844 * have the wrong values for the dso maps, so remove them. 934 * have the wrong values for the dso maps, so remove them.
845 */ 935 */
846 if (kmodule && syms_ss->symtab) 936 if (kmodule && syms_ss->symtab)
847 symbols__delete(&dso->symbols[map->type]); 937 symbols__delete(&dso->symbols);
848 938
849 if (!syms_ss->symtab) { 939 if (!syms_ss->symtab) {
850 /* 940 /*
@@ -921,10 +1011,10 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
921 1011
922 dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap); 1012 dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap);
923 /* 1013 /*
924 * Initial kernel and module mappings do not map to the dso. For 1014 * Initial kernel and module mappings do not map to the dso.
925 * function mappings, flag the fixups. 1015 * Flag the fixups.
926 */ 1016 */
927 if (map->type == MAP__FUNCTION && (dso->kernel || kmodule)) { 1017 if (dso->kernel || kmodule) {
928 remap_kernel = true; 1018 remap_kernel = true;
929 adjust_kernel_syms = dso->adjust_symbols; 1019 adjust_kernel_syms = dso->adjust_symbols;
930 } 1020 }
@@ -936,7 +1026,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
936 const char *section_name; 1026 const char *section_name;
937 bool used_opd = false; 1027 bool used_opd = false;
938 1028
939 if (!is_label && !elf_sym__is_a(&sym, map->type)) 1029 if (!is_label && !elf_sym__filter(&sym))
940 continue; 1030 continue;
941 1031
942 /* Reject ARM ELF "mapping symbols": these aren't unique and 1032 /* Reject ARM ELF "mapping symbols": these aren't unique and
@@ -974,7 +1064,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
974 1064
975 gelf_getshdr(sec, &shdr); 1065 gelf_getshdr(sec, &shdr);
976 1066
977 if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type)) 1067 if (is_label && !elf_sec__filter(&shdr, secstrs))
978 continue; 1068 continue;
979 1069
980 section_name = elf_sec__name(&shdr, secstrs); 1070 section_name = elf_sec__name(&shdr, secstrs);
@@ -982,134 +1072,37 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
982 /* On ARM, symbols for thumb functions have 1 added to 1072 /* On ARM, symbols for thumb functions have 1 added to
983 * the symbol address as a flag - remove it */ 1073 * the symbol address as a flag - remove it */
984 if ((ehdr.e_machine == EM_ARM) && 1074 if ((ehdr.e_machine == EM_ARM) &&
985 (map->type == MAP__FUNCTION) && 1075 (GELF_ST_TYPE(sym.st_info) == STT_FUNC) &&
986 (sym.st_value & 1)) 1076 (sym.st_value & 1))
987 --sym.st_value; 1077 --sym.st_value;
988 1078
989 if (dso->kernel || kmodule) { 1079 if (dso->kernel || kmodule) {
990 char dso_name[PATH_MAX]; 1080 if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map,
991 1081 section_name, adjust_kernel_syms, kmodule, &remap_kernel))
992 /* Adjust symbol to map to file offset */ 1082 goto out_elf_end;
993 if (adjust_kernel_syms) 1083 } else if ((used_opd && runtime_ss->adjust_symbols) ||
994 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 1084 (!used_opd && syms_ss->adjust_symbols)) {
995
996 if (strcmp(section_name,
997 (curr_dso->short_name +
998 dso->short_name_len)) == 0)
999 goto new_symbol;
1000
1001 if (strcmp(section_name, ".text") == 0) {
1002 /*
1003 * The initial kernel mapping is based on
1004 * kallsyms and identity maps. Overwrite it to
1005 * map to the kernel dso.
1006 */
1007 if (remap_kernel && dso->kernel) {
1008 remap_kernel = false;
1009 map->start = shdr.sh_addr +
1010 ref_reloc(kmap);
1011 map->end = map->start + shdr.sh_size;
1012 map->pgoff = shdr.sh_offset;
1013 map->map_ip = map__map_ip;
1014 map->unmap_ip = map__unmap_ip;
1015 /* Ensure maps are correctly ordered */
1016 if (kmaps) {
1017 map__get(map);
1018 map_groups__remove(kmaps, map);
1019 map_groups__insert(kmaps, map);
1020 map__put(map);
1021 }
1022 }
1023
1024 /*
1025 * The initial module mapping is based on
1026 * /proc/modules mapped to offset zero.
1027 * Overwrite it to map to the module dso.
1028 */
1029 if (remap_kernel && kmodule) {
1030 remap_kernel = false;
1031 map->pgoff = shdr.sh_offset;
1032 }
1033
1034 curr_map = map;
1035 curr_dso = dso;
1036 goto new_symbol;
1037 }
1038
1039 if (!kmap)
1040 goto new_symbol;
1041
1042 snprintf(dso_name, sizeof(dso_name),
1043 "%s%s", dso->short_name, section_name);
1044
1045 curr_map = map_groups__find_by_name(kmaps, map->type, dso_name);
1046 if (curr_map == NULL) {
1047 u64 start = sym.st_value;
1048
1049 if (kmodule)
1050 start += map->start + shdr.sh_offset;
1051
1052 curr_dso = dso__new(dso_name);
1053 if (curr_dso == NULL)
1054 goto out_elf_end;
1055 curr_dso->kernel = dso->kernel;
1056 curr_dso->long_name = dso->long_name;
1057 curr_dso->long_name_len = dso->long_name_len;
1058 curr_map = map__new2(start, curr_dso,
1059 map->type);
1060 dso__put(curr_dso);
1061 if (curr_map == NULL) {
1062 goto out_elf_end;
1063 }
1064 if (adjust_kernel_syms) {
1065 curr_map->start = shdr.sh_addr +
1066 ref_reloc(kmap);
1067 curr_map->end = curr_map->start +
1068 shdr.sh_size;
1069 curr_map->pgoff = shdr.sh_offset;
1070 } else {
1071 curr_map->map_ip = identity__map_ip;
1072 curr_map->unmap_ip = identity__map_ip;
1073 }
1074 curr_dso->symtab_type = dso->symtab_type;
1075 map_groups__insert(kmaps, curr_map);
1076 /*
1077 * Add it before we drop the referece to curr_map,
1078 * i.e. while we still are sure to have a reference
1079 * to this DSO via curr_map->dso.
1080 */
1081 dsos__add(&map->groups->machine->dsos, curr_dso);
1082 /* kmaps already got it */
1083 map__put(curr_map);
1084 dso__set_loaded(curr_dso, map->type);
1085 } else
1086 curr_dso = curr_map->dso;
1087
1088 goto new_symbol;
1089 }
1090
1091 if ((used_opd && runtime_ss->adjust_symbols)
1092 || (!used_opd && syms_ss->adjust_symbols)) {
1093 pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " " 1085 pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
1094 "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__, 1086 "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
1095 (u64)sym.st_value, (u64)shdr.sh_addr, 1087 (u64)sym.st_value, (u64)shdr.sh_addr,
1096 (u64)shdr.sh_offset); 1088 (u64)shdr.sh_offset);
1097 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 1089 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1098 } 1090 }
1099new_symbol: 1091
1100 demangled = demangle_sym(dso, kmodule, elf_name); 1092 demangled = demangle_sym(dso, kmodule, elf_name);
1101 if (demangled != NULL) 1093 if (demangled != NULL)
1102 elf_name = demangled; 1094 elf_name = demangled;
1103 1095
1104 f = symbol__new(sym.st_value, sym.st_size, 1096 f = symbol__new(sym.st_value, sym.st_size,
1105 GELF_ST_BIND(sym.st_info), elf_name); 1097 GELF_ST_BIND(sym.st_info),
1098 GELF_ST_TYPE(sym.st_info), elf_name);
1106 free(demangled); 1099 free(demangled);
1107 if (!f) 1100 if (!f)
1108 goto out_elf_end; 1101 goto out_elf_end;
1109 1102
1110 arch__sym_update(f, &sym); 1103 arch__sym_update(f, &sym);
1111 1104
1112 __symbols__insert(&curr_dso->symbols[curr_map->type], f, dso->kernel); 1105 __symbols__insert(&curr_dso->symbols, f, dso->kernel);
1113 nr++; 1106 nr++;
1114 } 1107 }
1115 1108
@@ -1117,14 +1110,14 @@ new_symbol:
1117 * For misannotated, zeroed, ASM function sizes. 1110 * For misannotated, zeroed, ASM function sizes.
1118 */ 1111 */
1119 if (nr > 0) { 1112 if (nr > 0) {
1120 symbols__fixup_end(&dso->symbols[map->type]); 1113 symbols__fixup_end(&dso->symbols);
1121 symbols__fixup_duplicate(&dso->symbols[map->type]); 1114 symbols__fixup_duplicate(&dso->symbols);
1122 if (kmap) { 1115 if (kmap) {
1123 /* 1116 /*
1124 * We need to fixup this here too because we create new 1117 * We need to fixup this here too because we create new
1125 * maps here, for things like vsyscall sections. 1118 * maps here, for things like vsyscall sections.
1126 */ 1119 */
1127 __map_groups__fixup_end(kmaps, map->type); 1120 map_groups__fixup_end(kmaps);
1128 } 1121 }
1129 } 1122 }
1130 err = nr; 1123 err = nr;
@@ -1413,7 +1406,7 @@ static int kcore_copy__process_kallsyms(void *arg, const char *name, char type,
1413{ 1406{
1414 struct kcore_copy_info *kci = arg; 1407 struct kcore_copy_info *kci = arg;
1415 1408
1416 if (!symbol_type__is_a(type, MAP__FUNCTION)) 1409 if (!kallsyms__is_function(type))
1417 return 0; 1410 return 0;
1418 1411
1419 if (strchr(name, '[')) { 1412 if (strchr(name, '[')) {
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index ff48d0d49584..7119df77dc0b 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -288,8 +288,7 @@ void symsrc__destroy(struct symsrc *ss)
288} 288}
289 289
290int dso__synthesize_plt_symbols(struct dso *dso __maybe_unused, 290int dso__synthesize_plt_symbols(struct dso *dso __maybe_unused,
291 struct symsrc *ss __maybe_unused, 291 struct symsrc *ss __maybe_unused)
292 struct map *map __maybe_unused)
293{ 292{
294 return 0; 293 return 0;
295} 294}
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 1466814ebada..f48dc157c2bd 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -5,6 +5,7 @@
5#include <stdio.h> 5#include <stdio.h>
6#include <string.h> 6#include <string.h>
7#include <linux/kernel.h> 7#include <linux/kernel.h>
8#include <linux/mman.h>
8#include <sys/types.h> 9#include <sys/types.h>
9#include <sys/stat.h> 10#include <sys/stat.h>
10#include <sys/param.h> 11#include <sys/param.h>
@@ -70,18 +71,10 @@ static enum dso_binary_type binary_type_symtab[] = {
70 71
71#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) 72#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
72 73
73bool symbol_type__is_a(char symbol_type, enum map_type map_type) 74static bool symbol_type__filter(char symbol_type)
74{ 75{
75 symbol_type = toupper(symbol_type); 76 symbol_type = toupper(symbol_type);
76 77 return symbol_type == 'T' || symbol_type == 'W' || symbol_type == 'D';
77 switch (map_type) {
78 case MAP__FUNCTION:
79 return symbol_type == 'T' || symbol_type == 'W';
80 case MAP__VARIABLE:
81 return symbol_type == 'D';
82 default:
83 return false;
84 }
85} 78}
86 79
87static int prefix_underscores_count(const char *str) 80static int prefix_underscores_count(const char *str)
@@ -228,9 +221,9 @@ void symbols__fixup_end(struct rb_root *symbols)
228 curr->end = roundup(curr->start, 4096) + 4096; 221 curr->end = roundup(curr->start, 4096) + 4096;
229} 222}
230 223
231void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) 224void map_groups__fixup_end(struct map_groups *mg)
232{ 225{
233 struct maps *maps = &mg->maps[type]; 226 struct maps *maps = &mg->maps;
234 struct map *next, *curr; 227 struct map *next, *curr;
235 228
236 down_write(&maps->lock); 229 down_write(&maps->lock);
@@ -256,7 +249,7 @@ out_unlock:
256 up_write(&maps->lock); 249 up_write(&maps->lock);
257} 250}
258 251
259struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name) 252struct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const char *name)
260{ 253{
261 size_t namelen = strlen(name) + 1; 254 size_t namelen = strlen(name) + 1;
262 struct symbol *sym = calloc(1, (symbol_conf.priv_size + 255 struct symbol *sym = calloc(1, (symbol_conf.priv_size +
@@ -274,6 +267,7 @@ struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name)
274 267
275 sym->start = start; 268 sym->start = start;
276 sym->end = len ? start + len : start; 269 sym->end = len ? start + len : start;
270 sym->type = type;
277 sym->binding = binding; 271 sym->binding = binding;
278 sym->namelen = namelen - 1; 272 sym->namelen = namelen - 1;
279 273
@@ -484,45 +478,40 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols,
484 478
485void dso__reset_find_symbol_cache(struct dso *dso) 479void dso__reset_find_symbol_cache(struct dso *dso)
486{ 480{
487 enum map_type type; 481 dso->last_find_result.addr = 0;
488 482 dso->last_find_result.symbol = NULL;
489 for (type = MAP__FUNCTION; type <= MAP__VARIABLE; ++type) {
490 dso->last_find_result[type].addr = 0;
491 dso->last_find_result[type].symbol = NULL;
492 }
493} 483}
494 484
495void dso__insert_symbol(struct dso *dso, enum map_type type, struct symbol *sym) 485void dso__insert_symbol(struct dso *dso, struct symbol *sym)
496{ 486{
497 __symbols__insert(&dso->symbols[type], sym, dso->kernel); 487 __symbols__insert(&dso->symbols, sym, dso->kernel);
498 488
499 /* update the symbol cache if necessary */ 489 /* update the symbol cache if necessary */
500 if (dso->last_find_result[type].addr >= sym->start && 490 if (dso->last_find_result.addr >= sym->start &&
501 (dso->last_find_result[type].addr < sym->end || 491 (dso->last_find_result.addr < sym->end ||
502 sym->start == sym->end)) { 492 sym->start == sym->end)) {
503 dso->last_find_result[type].symbol = sym; 493 dso->last_find_result.symbol = sym;
504 } 494 }
505} 495}
506 496
507struct symbol *dso__find_symbol(struct dso *dso, 497struct symbol *dso__find_symbol(struct dso *dso, u64 addr)
508 enum map_type type, u64 addr)
509{ 498{
510 if (dso->last_find_result[type].addr != addr || dso->last_find_result[type].symbol == NULL) { 499 if (dso->last_find_result.addr != addr || dso->last_find_result.symbol == NULL) {
511 dso->last_find_result[type].addr = addr; 500 dso->last_find_result.addr = addr;
512 dso->last_find_result[type].symbol = symbols__find(&dso->symbols[type], addr); 501 dso->last_find_result.symbol = symbols__find(&dso->symbols, addr);
513 } 502 }
514 503
515 return dso->last_find_result[type].symbol; 504 return dso->last_find_result.symbol;
516} 505}
517 506
518struct symbol *dso__first_symbol(struct dso *dso, enum map_type type) 507struct symbol *dso__first_symbol(struct dso *dso)
519{ 508{
520 return symbols__first(&dso->symbols[type]); 509 return symbols__first(&dso->symbols);
521} 510}
522 511
523struct symbol *dso__last_symbol(struct dso *dso, enum map_type type) 512struct symbol *dso__last_symbol(struct dso *dso)
524{ 513{
525 return symbols__last(&dso->symbols[type]); 514 return symbols__last(&dso->symbols);
526} 515}
527 516
528struct symbol *dso__next_symbol(struct symbol *sym) 517struct symbol *dso__next_symbol(struct symbol *sym)
@@ -539,24 +528,22 @@ struct symbol *symbol__next_by_name(struct symbol *sym)
539} 528}
540 529
541 /* 530 /*
542 * Teturns first symbol that matched with @name. 531 * Returns first symbol that matched with @name.
543 */ 532 */
544struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, 533struct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name)
545 const char *name)
546{ 534{
547 struct symbol *s = symbols__find_by_name(&dso->symbol_names[type], name, 535 struct symbol *s = symbols__find_by_name(&dso->symbol_names, name,
548 SYMBOL_TAG_INCLUDE__NONE); 536 SYMBOL_TAG_INCLUDE__NONE);
549 if (!s) 537 if (!s)
550 s = symbols__find_by_name(&dso->symbol_names[type], name, 538 s = symbols__find_by_name(&dso->symbol_names, name,
551 SYMBOL_TAG_INCLUDE__DEFAULT_ONLY); 539 SYMBOL_TAG_INCLUDE__DEFAULT_ONLY);
552 return s; 540 return s;
553} 541}
554 542
555void dso__sort_by_name(struct dso *dso, enum map_type type) 543void dso__sort_by_name(struct dso *dso)
556{ 544{
557 dso__set_sorted_by_name(dso, type); 545 dso__set_sorted_by_name(dso);
558 return symbols__sort_by_name(&dso->symbol_names[type], 546 return symbols__sort_by_name(&dso->symbol_names, &dso->symbols);
559 &dso->symbols[type]);
560} 547}
561 548
562int modules__parse(const char *filename, void *arg, 549int modules__parse(const char *filename, void *arg,
@@ -621,11 +608,6 @@ out:
621 return err; 608 return err;
622} 609}
623 610
624struct process_kallsyms_args {
625 struct map *map;
626 struct dso *dso;
627};
628
629/* 611/*
630 * These are symbols in the kernel image, so make sure that 612 * These are symbols in the kernel image, so make sure that
631 * sym is from a kernel DSO. 613 * sym is from a kernel DSO.
@@ -661,10 +643,10 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
661 char type, u64 start) 643 char type, u64 start)
662{ 644{
663 struct symbol *sym; 645 struct symbol *sym;
664 struct process_kallsyms_args *a = arg; 646 struct dso *dso = arg;
665 struct rb_root *root = &a->dso->symbols[a->map->type]; 647 struct rb_root *root = &dso->symbols;
666 648
667 if (!symbol_type__is_a(type, a->map->type)) 649 if (!symbol_type__filter(type))
668 return 0; 650 return 0;
669 651
670 /* 652 /*
@@ -672,7 +654,7 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
672 * symbols, setting length to 0, and rely on 654 * symbols, setting length to 0, and rely on
673 * symbols__fixup_end() to fix it up. 655 * symbols__fixup_end() to fix it up.
674 */ 656 */
675 sym = symbol__new(start, 0, kallsyms2elf_binding(type), name); 657 sym = symbol__new(start, 0, kallsyms2elf_binding(type), kallsyms2elf_type(type), name);
676 if (sym == NULL) 658 if (sym == NULL)
677 return -ENOMEM; 659 return -ENOMEM;
678 /* 660 /*
@@ -689,21 +671,18 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
689 * so that we can in the next step set the symbol ->end address and then 671 * so that we can in the next step set the symbol ->end address and then
690 * call kernel_maps__split_kallsyms. 672 * call kernel_maps__split_kallsyms.
691 */ 673 */
692static int dso__load_all_kallsyms(struct dso *dso, const char *filename, 674static int dso__load_all_kallsyms(struct dso *dso, const char *filename)
693 struct map *map)
694{ 675{
695 struct process_kallsyms_args args = { .map = map, .dso = dso, }; 676 return kallsyms__parse(filename, dso, map__process_kallsym_symbol);
696 return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
697} 677}
698 678
699static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map) 679static int map_groups__split_kallsyms_for_kcore(struct map_groups *kmaps, struct dso *dso)
700{ 680{
701 struct map_groups *kmaps = map__kmaps(map);
702 struct map *curr_map; 681 struct map *curr_map;
703 struct symbol *pos; 682 struct symbol *pos;
704 int count = 0; 683 int count = 0;
705 struct rb_root old_root = dso->symbols[map->type]; 684 struct rb_root old_root = dso->symbols;
706 struct rb_root *root = &dso->symbols[map->type]; 685 struct rb_root *root = &dso->symbols;
707 struct rb_node *next = rb_first(root); 686 struct rb_node *next = rb_first(root);
708 687
709 if (!kmaps) 688 if (!kmaps)
@@ -723,7 +702,7 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map)
723 if (module) 702 if (module)
724 *module = '\0'; 703 *module = '\0';
725 704
726 curr_map = map_groups__find(kmaps, map->type, pos->start); 705 curr_map = map_groups__find(kmaps, pos->start);
727 706
728 if (!curr_map) { 707 if (!curr_map) {
729 symbol__delete(pos); 708 symbol__delete(pos);
@@ -733,7 +712,7 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map)
733 pos->start -= curr_map->start - curr_map->pgoff; 712 pos->start -= curr_map->start - curr_map->pgoff;
734 if (pos->end) 713 if (pos->end)
735 pos->end -= curr_map->start - curr_map->pgoff; 714 pos->end -= curr_map->start - curr_map->pgoff;
736 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); 715 symbols__insert(&curr_map->dso->symbols, pos);
737 ++count; 716 ++count;
738 } 717 }
739 718
@@ -748,14 +727,14 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map)
748 * kernel range is broken in several maps, named [kernel].N, as we don't have 727 * kernel range is broken in several maps, named [kernel].N, as we don't have
749 * the original ELF section names vmlinux have. 728 * the original ELF section names vmlinux have.
750 */ 729 */
751static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta) 730static int map_groups__split_kallsyms(struct map_groups *kmaps, struct dso *dso, u64 delta,
731 struct map *initial_map)
752{ 732{
753 struct map_groups *kmaps = map__kmaps(map);
754 struct machine *machine; 733 struct machine *machine;
755 struct map *curr_map = map; 734 struct map *curr_map = initial_map;
756 struct symbol *pos; 735 struct symbol *pos;
757 int count = 0, moved = 0; 736 int count = 0, moved = 0;
758 struct rb_root *root = &dso->symbols[map->type]; 737 struct rb_root *root = &dso->symbols;
759 struct rb_node *next = rb_first(root); 738 struct rb_node *next = rb_first(root);
760 int kernel_range = 0; 739 int kernel_range = 0;
761 740
@@ -778,7 +757,7 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta)
778 *module++ = '\0'; 757 *module++ = '\0';
779 758
780 if (strcmp(curr_map->dso->short_name, module)) { 759 if (strcmp(curr_map->dso->short_name, module)) {
781 if (curr_map != map && 760 if (curr_map != initial_map &&
782 dso->kernel == DSO_TYPE_GUEST_KERNEL && 761 dso->kernel == DSO_TYPE_GUEST_KERNEL &&
783 machine__is_default_guest(machine)) { 762 machine__is_default_guest(machine)) {
784 /* 763 /*
@@ -788,18 +767,16 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta)
788 * symbols are in its kmap. Mark it as 767 * symbols are in its kmap. Mark it as
789 * loaded. 768 * loaded.
790 */ 769 */
791 dso__set_loaded(curr_map->dso, 770 dso__set_loaded(curr_map->dso);
792 curr_map->type);
793 } 771 }
794 772
795 curr_map = map_groups__find_by_name(kmaps, 773 curr_map = map_groups__find_by_name(kmaps, module);
796 map->type, module);
797 if (curr_map == NULL) { 774 if (curr_map == NULL) {
798 pr_debug("%s/proc/{kallsyms,modules} " 775 pr_debug("%s/proc/{kallsyms,modules} "
799 "inconsistency while looking " 776 "inconsistency while looking "
800 "for \"%s\" module!\n", 777 "for \"%s\" module!\n",
801 machine->root_dir, module); 778 machine->root_dir, module);
802 curr_map = map; 779 curr_map = initial_map;
803 goto discard_symbol; 780 goto discard_symbol;
804 } 781 }
805 782
@@ -809,11 +786,11 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta)
809 } 786 }
810 /* 787 /*
811 * So that we look just like we get from .ko files, 788 * So that we look just like we get from .ko files,
812 * i.e. not prelinked, relative to map->start. 789 * i.e. not prelinked, relative to initial_map->start.
813 */ 790 */
814 pos->start = curr_map->map_ip(curr_map, pos->start); 791 pos->start = curr_map->map_ip(curr_map, pos->start);
815 pos->end = curr_map->map_ip(curr_map, pos->end); 792 pos->end = curr_map->map_ip(curr_map, pos->end);
816 } else if (curr_map != map) { 793 } else if (curr_map != initial_map) {
817 char dso_name[PATH_MAX]; 794 char dso_name[PATH_MAX];
818 struct dso *ndso; 795 struct dso *ndso;
819 796
@@ -824,7 +801,7 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta)
824 } 801 }
825 802
826 if (count == 0) { 803 if (count == 0) {
827 curr_map = map; 804 curr_map = initial_map;
828 goto add_symbol; 805 goto add_symbol;
829 } 806 }
830 807
@@ -843,7 +820,7 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta)
843 820
844 ndso->kernel = dso->kernel; 821 ndso->kernel = dso->kernel;
845 822
846 curr_map = map__new2(pos->start, ndso, map->type); 823 curr_map = map__new2(pos->start, ndso);
847 if (curr_map == NULL) { 824 if (curr_map == NULL) {
848 dso__put(ndso); 825 dso__put(ndso);
849 return -1; 826 return -1;
@@ -858,9 +835,9 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta)
858 pos->end -= delta; 835 pos->end -= delta;
859 } 836 }
860add_symbol: 837add_symbol:
861 if (curr_map != map) { 838 if (curr_map != initial_map) {
862 rb_erase(&pos->rb_node, root); 839 rb_erase(&pos->rb_node, root);
863 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); 840 symbols__insert(&curr_map->dso->symbols, pos);
864 ++moved; 841 ++moved;
865 } else 842 } else
866 ++count; 843 ++count;
@@ -871,10 +848,10 @@ discard_symbol:
871 symbol__delete(pos); 848 symbol__delete(pos);
872 } 849 }
873 850
874 if (curr_map != map && 851 if (curr_map != initial_map &&
875 dso->kernel == DSO_TYPE_GUEST_KERNEL && 852 dso->kernel == DSO_TYPE_GUEST_KERNEL &&
876 machine__is_default_guest(kmaps->machine)) { 853 machine__is_default_guest(kmaps->machine)) {
877 dso__set_loaded(curr_map->dso, curr_map->type); 854 dso__set_loaded(curr_map->dso);
878 } 855 }
879 856
880 return count + moved; 857 return count + moved;
@@ -1035,6 +1012,11 @@ out_delete_from:
1035 return ret; 1012 return ret;
1036} 1013}
1037 1014
1015struct map *map_groups__first(struct map_groups *mg)
1016{
1017 return maps__first(&mg->maps);
1018}
1019
1038static int do_validate_kcore_modules(const char *filename, struct map *map, 1020static int do_validate_kcore_modules(const char *filename, struct map *map,
1039 struct map_groups *kmaps) 1021 struct map_groups *kmaps)
1040{ 1022{
@@ -1046,7 +1028,7 @@ static int do_validate_kcore_modules(const char *filename, struct map *map,
1046 if (err) 1028 if (err)
1047 return err; 1029 return err;
1048 1030
1049 old_map = map_groups__first(kmaps, map->type); 1031 old_map = map_groups__first(kmaps);
1050 while (old_map) { 1032 while (old_map) {
1051 struct map *next = map_groups__next(old_map); 1033 struct map *next = map_groups__next(old_map);
1052 struct module_info *mi; 1034 struct module_info *mi;
@@ -1138,7 +1120,6 @@ static int validate_kcore_addresses(const char *kallsyms_filename,
1138 1120
1139struct kcore_mapfn_data { 1121struct kcore_mapfn_data {
1140 struct dso *dso; 1122 struct dso *dso;
1141 enum map_type type;
1142 struct list_head maps; 1123 struct list_head maps;
1143}; 1124};
1144 1125
@@ -1147,7 +1128,7 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
1147 struct kcore_mapfn_data *md = data; 1128 struct kcore_mapfn_data *md = data;
1148 struct map *map; 1129 struct map *map;
1149 1130
1150 map = map__new2(start, md->dso, md->type); 1131 map = map__new2(start, md->dso);
1151 if (map == NULL) 1132 if (map == NULL)
1152 return -ENOMEM; 1133 return -ENOMEM;
1153 1134
@@ -1163,7 +1144,6 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1163 const char *kallsyms_filename) 1144 const char *kallsyms_filename)
1164{ 1145{
1165 struct map_groups *kmaps = map__kmaps(map); 1146 struct map_groups *kmaps = map__kmaps(map);
1166 struct machine *machine;
1167 struct kcore_mapfn_data md; 1147 struct kcore_mapfn_data md;
1168 struct map *old_map, *new_map, *replacement_map = NULL; 1148 struct map *old_map, *new_map, *replacement_map = NULL;
1169 bool is_64_bit; 1149 bool is_64_bit;
@@ -1174,10 +1154,8 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1174 if (!kmaps) 1154 if (!kmaps)
1175 return -EINVAL; 1155 return -EINVAL;
1176 1156
1177 machine = kmaps->machine;
1178
1179 /* This function requires that the map is the kernel map */ 1157 /* This function requires that the map is the kernel map */
1180 if (map != machine->vmlinux_maps[map->type]) 1158 if (!__map__is_kernel(map))
1181 return -EINVAL; 1159 return -EINVAL;
1182 1160
1183 if (!filename_from_kallsyms_filename(kcore_filename, "kcore", 1161 if (!filename_from_kallsyms_filename(kcore_filename, "kcore",
@@ -1189,7 +1167,6 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1189 return -EINVAL; 1167 return -EINVAL;
1190 1168
1191 md.dso = dso; 1169 md.dso = dso;
1192 md.type = map->type;
1193 INIT_LIST_HEAD(&md.maps); 1170 INIT_LIST_HEAD(&md.maps);
1194 1171
1195 fd = open(kcore_filename, O_RDONLY); 1172 fd = open(kcore_filename, O_RDONLY);
@@ -1200,7 +1177,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1200 } 1177 }
1201 1178
1202 /* Read new maps into temporary lists */ 1179 /* Read new maps into temporary lists */
1203 err = file__read_maps(fd, md.type == MAP__FUNCTION, kcore_mapfn, &md, 1180 err = file__read_maps(fd, map->prot & PROT_EXEC, kcore_mapfn, &md,
1204 &is_64_bit); 1181 &is_64_bit);
1205 if (err) 1182 if (err)
1206 goto out_err; 1183 goto out_err;
@@ -1212,7 +1189,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1212 } 1189 }
1213 1190
1214 /* Remove old maps */ 1191 /* Remove old maps */
1215 old_map = map_groups__first(kmaps, map->type); 1192 old_map = map_groups__first(kmaps);
1216 while (old_map) { 1193 while (old_map) {
1217 struct map *next = map_groups__next(old_map); 1194 struct map *next = map_groups__next(old_map);
1218 1195
@@ -1222,7 +1199,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1222 } 1199 }
1223 1200
1224 /* Find the kernel map using the first symbol */ 1201 /* Find the kernel map using the first symbol */
1225 sym = dso__first_symbol(dso, map->type); 1202 sym = dso__first_symbol(dso);
1226 list_for_each_entry(new_map, &md.maps, node) { 1203 list_for_each_entry(new_map, &md.maps, node) {
1227 if (sym && sym->start >= new_map->start && 1204 if (sym && sym->start >= new_map->start &&
1228 sym->start < new_map->end) { 1205 sym->start < new_map->end) {
@@ -1268,7 +1245,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1268 1245
1269 close(fd); 1246 close(fd);
1270 1247
1271 if (map->type == MAP__FUNCTION) 1248 if (map->prot & PROT_EXEC)
1272 pr_debug("Using %s for kernel object code\n", kcore_filename); 1249 pr_debug("Using %s for kernel object code\n", kcore_filename);
1273 else 1250 else
1274 pr_debug("Using %s for kernel data\n", kcore_filename); 1251 pr_debug("Using %s for kernel data\n", kcore_filename);
@@ -1289,14 +1266,10 @@ out_err:
1289 * If the kernel is relocated at boot time, kallsyms won't match. Compute the 1266 * If the kernel is relocated at boot time, kallsyms won't match. Compute the
1290 * delta based on the relocation reference symbol. 1267 * delta based on the relocation reference symbol.
1291 */ 1268 */
1292static int kallsyms__delta(struct map *map, const char *filename, u64 *delta) 1269static int kallsyms__delta(struct kmap *kmap, const char *filename, u64 *delta)
1293{ 1270{
1294 struct kmap *kmap = map__kmap(map);
1295 u64 addr; 1271 u64 addr;
1296 1272
1297 if (!kmap)
1298 return -1;
1299
1300 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name) 1273 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name)
1301 return 0; 1274 return 0;
1302 1275
@@ -1310,19 +1283,23 @@ static int kallsyms__delta(struct map *map, const char *filename, u64 *delta)
1310int __dso__load_kallsyms(struct dso *dso, const char *filename, 1283int __dso__load_kallsyms(struct dso *dso, const char *filename,
1311 struct map *map, bool no_kcore) 1284 struct map *map, bool no_kcore)
1312{ 1285{
1286 struct kmap *kmap = map__kmap(map);
1313 u64 delta = 0; 1287 u64 delta = 0;
1314 1288
1315 if (symbol__restricted_filename(filename, "/proc/kallsyms")) 1289 if (symbol__restricted_filename(filename, "/proc/kallsyms"))
1316 return -1; 1290 return -1;
1317 1291
1318 if (dso__load_all_kallsyms(dso, filename, map) < 0) 1292 if (!kmap || !kmap->kmaps)
1293 return -1;
1294
1295 if (dso__load_all_kallsyms(dso, filename) < 0)
1319 return -1; 1296 return -1;
1320 1297
1321 if (kallsyms__delta(map, filename, &delta)) 1298 if (kallsyms__delta(kmap, filename, &delta))
1322 return -1; 1299 return -1;
1323 1300
1324 symbols__fixup_end(&dso->symbols[map->type]); 1301 symbols__fixup_end(&dso->symbols);
1325 symbols__fixup_duplicate(&dso->symbols[map->type]); 1302 symbols__fixup_duplicate(&dso->symbols);
1326 1303
1327 if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1304 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1328 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; 1305 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
@@ -1330,9 +1307,9 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename,
1330 dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS; 1307 dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;
1331 1308
1332 if (!no_kcore && !dso__load_kcore(dso, map, filename)) 1309 if (!no_kcore && !dso__load_kcore(dso, map, filename))
1333 return dso__split_kallsyms_for_kcore(dso, map); 1310 return map_groups__split_kallsyms_for_kcore(kmap->kmaps, dso);
1334 else 1311 else
1335 return dso__split_kallsyms(dso, map, delta); 1312 return map_groups__split_kallsyms(kmap->kmaps, dso, delta, map);
1336} 1313}
1337 1314
1338int dso__load_kallsyms(struct dso *dso, const char *filename, 1315int dso__load_kallsyms(struct dso *dso, const char *filename,
@@ -1341,8 +1318,7 @@ int dso__load_kallsyms(struct dso *dso, const char *filename,
1341 return __dso__load_kallsyms(dso, filename, map, false); 1318 return __dso__load_kallsyms(dso, filename, map, false);
1342} 1319}
1343 1320
1344static int dso__load_perf_map(const char *map_path, struct dso *dso, 1321static int dso__load_perf_map(const char *map_path, struct dso *dso)
1345 struct map *map)
1346{ 1322{
1347 char *line = NULL; 1323 char *line = NULL;
1348 size_t n; 1324 size_t n;
@@ -1379,12 +1355,12 @@ static int dso__load_perf_map(const char *map_path, struct dso *dso,
1379 if (len + 2 >= line_len) 1355 if (len + 2 >= line_len)
1380 continue; 1356 continue;
1381 1357
1382 sym = symbol__new(start, size, STB_GLOBAL, line + len); 1358 sym = symbol__new(start, size, STB_GLOBAL, STT_FUNC, line + len);
1383 1359
1384 if (sym == NULL) 1360 if (sym == NULL)
1385 goto out_delete_line; 1361 goto out_delete_line;
1386 1362
1387 symbols__insert(&dso->symbols[map->type], sym); 1363 symbols__insert(&dso->symbols, sym);
1388 nr_syms++; 1364 nr_syms++;
1389 } 1365 }
1390 1366
@@ -1509,7 +1485,7 @@ int dso__load(struct dso *dso, struct map *map)
1509 pthread_mutex_lock(&dso->lock); 1485 pthread_mutex_lock(&dso->lock);
1510 1486
1511 /* check again under the dso->lock */ 1487 /* check again under the dso->lock */
1512 if (dso__loaded(dso, map->type)) { 1488 if (dso__loaded(dso)) {
1513 ret = 1; 1489 ret = 1;
1514 goto out; 1490 goto out;
1515 } 1491 }
@@ -1542,7 +1518,7 @@ int dso__load(struct dso *dso, struct map *map)
1542 goto out; 1518 goto out;
1543 } 1519 }
1544 1520
1545 ret = dso__load_perf_map(map_path, dso, map); 1521 ret = dso__load_perf_map(map_path, dso);
1546 dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT : 1522 dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT :
1547 DSO_BINARY_TYPE__NOT_FOUND; 1523 DSO_BINARY_TYPE__NOT_FOUND;
1548 goto out; 1524 goto out;
@@ -1651,7 +1627,7 @@ int dso__load(struct dso *dso, struct map *map)
1651 if (ret > 0) { 1627 if (ret > 0) {
1652 int nr_plt; 1628 int nr_plt;
1653 1629
1654 nr_plt = dso__synthesize_plt_symbols(dso, runtime_ss, map); 1630 nr_plt = dso__synthesize_plt_symbols(dso, runtime_ss);
1655 if (nr_plt > 0) 1631 if (nr_plt > 0)
1656 ret += nr_plt; 1632 ret += nr_plt;
1657 } 1633 }
@@ -1663,17 +1639,16 @@ out_free:
1663 if (ret < 0 && strstr(dso->name, " (deleted)") != NULL) 1639 if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
1664 ret = 0; 1640 ret = 0;
1665out: 1641out:
1666 dso__set_loaded(dso, map->type); 1642 dso__set_loaded(dso);
1667 pthread_mutex_unlock(&dso->lock); 1643 pthread_mutex_unlock(&dso->lock);
1668 nsinfo__mountns_exit(&nsc); 1644 nsinfo__mountns_exit(&nsc);
1669 1645
1670 return ret; 1646 return ret;
1671} 1647}
1672 1648
1673struct map *map_groups__find_by_name(struct map_groups *mg, 1649struct map *map_groups__find_by_name(struct map_groups *mg, const char *name)
1674 enum map_type type, const char *name)
1675{ 1650{
1676 struct maps *maps = &mg->maps[type]; 1651 struct maps *maps = &mg->maps;
1677 struct map *map; 1652 struct map *map;
1678 1653
1679 down_read(&maps->lock); 1654 down_read(&maps->lock);
@@ -1720,7 +1695,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map,
1720 else 1695 else
1721 dso->binary_type = DSO_BINARY_TYPE__VMLINUX; 1696 dso->binary_type = DSO_BINARY_TYPE__VMLINUX;
1722 dso__set_long_name(dso, vmlinux, vmlinux_allocated); 1697 dso__set_long_name(dso, vmlinux, vmlinux_allocated);
1723 dso__set_loaded(dso, map->type); 1698 dso__set_loaded(dso);
1724 pr_debug("Using %s for symbols\n", symfs_vmlinux); 1699 pr_debug("Using %s for symbols\n", symfs_vmlinux);
1725 } 1700 }
1726 1701
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 70c16741f50a..1a16438eb3ce 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -57,7 +57,8 @@ struct symbol {
57 u64 start; 57 u64 start;
58 u64 end; 58 u64 end;
59 u16 namelen; 59 u16 namelen;
60 u8 binding; 60 u8 type:4;
61 u8 binding:4;
61 u8 idle:1; 62 u8 idle:1;
62 u8 ignore:1; 63 u8 ignore:1;
63 u8 inlined:1; 64 u8 inlined:1;
@@ -259,17 +260,16 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
259 bool no_kcore); 260 bool no_kcore);
260int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map); 261int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map);
261 262
262void dso__insert_symbol(struct dso *dso, enum map_type type, 263void dso__insert_symbol(struct dso *dso,
263 struct symbol *sym); 264 struct symbol *sym);
264 265
265struct symbol *dso__find_symbol(struct dso *dso, enum map_type type, 266struct symbol *dso__find_symbol(struct dso *dso, u64 addr);
266 u64 addr); 267struct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name);
267struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, 268
268 const char *name);
269struct symbol *symbol__next_by_name(struct symbol *sym); 269struct symbol *symbol__next_by_name(struct symbol *sym);
270 270
271struct symbol *dso__first_symbol(struct dso *dso, enum map_type type); 271struct symbol *dso__first_symbol(struct dso *dso);
272struct symbol *dso__last_symbol(struct dso *dso, enum map_type type); 272struct symbol *dso__last_symbol(struct dso *dso);
273struct symbol *dso__next_symbol(struct symbol *sym); 273struct symbol *dso__next_symbol(struct symbol *sym);
274 274
275enum dso_type dso__type_fd(int fd); 275enum dso_type dso__type_fd(int fd);
@@ -288,7 +288,7 @@ void symbol__exit(void);
288void symbol__elf_init(void); 288void symbol__elf_init(void);
289int symbol__annotation_init(void); 289int symbol__annotation_init(void);
290 290
291struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name); 291struct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const char *name);
292size_t __symbol__fprintf_symname_offs(const struct symbol *sym, 292size_t __symbol__fprintf_symname_offs(const struct symbol *sym,
293 const struct addr_location *al, 293 const struct addr_location *al,
294 bool unknown_as_addr, 294 bool unknown_as_addr,
@@ -300,7 +300,6 @@ size_t __symbol__fprintf_symname(const struct symbol *sym,
300 bool unknown_as_addr, FILE *fp); 300 bool unknown_as_addr, FILE *fp);
301size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp); 301size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
302size_t symbol__fprintf(struct symbol *sym, FILE *fp); 302size_t symbol__fprintf(struct symbol *sym, FILE *fp);
303bool symbol_type__is_a(char symbol_type, enum map_type map_type);
304bool symbol__restricted_filename(const char *filename, 303bool symbol__restricted_filename(const char *filename,
305 const char *restricted_filename); 304 const char *restricted_filename);
306int symbol__config_symfs(const struct option *opt __maybe_unused, 305int symbol__config_symfs(const struct option *opt __maybe_unused,
@@ -308,8 +307,7 @@ int symbol__config_symfs(const struct option *opt __maybe_unused,
308 307
309int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, 308int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
310 struct symsrc *runtime_ss, int kmodule); 309 struct symsrc *runtime_ss, int kmodule);
311int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, 310int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss);
312 struct map *map);
313 311
314char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name); 312char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name);
315 313
@@ -317,7 +315,7 @@ void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel)
317void symbols__insert(struct rb_root *symbols, struct symbol *sym); 315void symbols__insert(struct rb_root *symbols, struct symbol *sym);
318void symbols__fixup_duplicate(struct rb_root *symbols); 316void symbols__fixup_duplicate(struct rb_root *symbols);
319void symbols__fixup_end(struct rb_root *symbols); 317void symbols__fixup_end(struct rb_root *symbols);
320void __map_groups__fixup_end(struct map_groups *mg, enum map_type type); 318void map_groups__fixup_end(struct map_groups *mg);
321 319
322typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data); 320typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data);
323int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data, 321int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
diff --git a/tools/perf/util/symbol_fprintf.c b/tools/perf/util/symbol_fprintf.c
index 6dd2cb88ccbe..ed0205cc7942 100644
--- a/tools/perf/util/symbol_fprintf.c
+++ b/tools/perf/util/symbol_fprintf.c
@@ -58,13 +58,13 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
58} 58}
59 59
60size_t dso__fprintf_symbols_by_name(struct dso *dso, 60size_t dso__fprintf_symbols_by_name(struct dso *dso,
61 enum map_type type, FILE *fp) 61 FILE *fp)
62{ 62{
63 size_t ret = 0; 63 size_t ret = 0;
64 struct rb_node *nd; 64 struct rb_node *nd;
65 struct symbol_name_rb_node *pos; 65 struct symbol_name_rb_node *pos;
66 66
67 for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) { 67 for (nd = rb_first(&dso->symbol_names); nd; nd = rb_next(nd)) {
68 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); 68 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
69 fprintf(fp, "%s\n", pos->sym.name); 69 fprintf(fp, "%s\n", pos->sym.name);
70 } 70 }
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 68b65b10579b..2048d393ece6 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -302,23 +302,20 @@ int thread__insert_map(struct thread *thread, struct map *map)
302static int __thread__prepare_access(struct thread *thread) 302static int __thread__prepare_access(struct thread *thread)
303{ 303{
304 bool initialized = false; 304 bool initialized = false;
305 int i, err = 0; 305 int err = 0;
306 306 struct maps *maps = &thread->mg->maps;
307 for (i = 0; i < MAP__NR_TYPES; ++i) { 307 struct map *map;
308 struct maps *maps = &thread->mg->maps[i];
309 struct map *map;
310 308
311 down_read(&maps->lock); 309 down_read(&maps->lock);
312 310
313 for (map = maps__first(maps); map; map = map__next(map)) { 311 for (map = maps__first(maps); map; map = map__next(map)) {
314 err = unwind__prepare_access(thread, map, &initialized); 312 err = unwind__prepare_access(thread, map, &initialized);
315 if (err || initialized) 313 if (err || initialized)
316 break; 314 break;
317 }
318
319 up_read(&maps->lock);
320 } 315 }
321 316
317 up_read(&maps->lock);
318
322 return err; 319 return err;
323} 320}
324 321
@@ -335,8 +332,6 @@ static int thread__prepare_access(struct thread *thread)
335static int thread__clone_map_groups(struct thread *thread, 332static int thread__clone_map_groups(struct thread *thread,
336 struct thread *parent) 333 struct thread *parent)
337{ 334{
338 int i;
339
340 /* This is new thread, we share map groups for process. */ 335 /* This is new thread, we share map groups for process. */
341 if (thread->pid_ == parent->pid_) 336 if (thread->pid_ == parent->pid_)
342 return thread__prepare_access(thread); 337 return thread__prepare_access(thread);
@@ -348,9 +343,8 @@ static int thread__clone_map_groups(struct thread *thread,
348 } 343 }
349 344
350 /* But this one is new process, copy maps. */ 345 /* But this one is new process, copy maps. */
351 for (i = 0; i < MAP__NR_TYPES; ++i) 346 if (map_groups__clone(thread, parent->mg) < 0)
352 if (map_groups__clone(thread, parent->mg, i) < 0) 347 return -ENOMEM;
353 return -ENOMEM;
354 348
355 return 0; 349 return 0;
356} 350}
@@ -371,8 +365,7 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
371 return thread__clone_map_groups(thread, parent); 365 return thread__clone_map_groups(thread, parent);
372} 366}
373 367
374void thread__find_cpumode_addr_location(struct thread *thread, 368void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
375 enum map_type type, u64 addr,
376 struct addr_location *al) 369 struct addr_location *al)
377{ 370{
378 size_t i; 371 size_t i;
@@ -384,7 +377,7 @@ void thread__find_cpumode_addr_location(struct thread *thread,
384 }; 377 };
385 378
386 for (i = 0; i < ARRAY_SIZE(cpumodes); i++) { 379 for (i = 0; i < ARRAY_SIZE(cpumodes); i++) {
387 thread__find_addr_location(thread, cpumodes[i], type, addr, al); 380 thread__find_symbol(thread, cpumodes[i], addr, al);
388 if (al->map) 381 if (al->map)
389 break; 382 break;
390 } 383 }
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 14d44c3235b8..07606aa6998d 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -92,16 +92,13 @@ size_t thread__fprintf(struct thread *thread, FILE *fp);
92 92
93struct thread *thread__main_thread(struct machine *machine, struct thread *thread); 93struct thread *thread__main_thread(struct machine *machine, struct thread *thread);
94 94
95void thread__find_addr_map(struct thread *thread, 95struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
96 u8 cpumode, enum map_type type, u64 addr, 96 struct addr_location *al);
97 struct addr_location *al);
98 97
99void thread__find_addr_location(struct thread *thread, 98struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
100 u8 cpumode, enum map_type type, u64 addr, 99 u64 addr, struct addr_location *al);
101 struct addr_location *al);
102 100
103void thread__find_cpumode_addr_location(struct thread *thread, 101void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
104 enum map_type type, u64 addr,
105 struct addr_location *al); 102 struct addr_location *al);
106 103
107static inline void *thread__priv(struct thread *thread) 104static inline void *thread__priv(struct thread *thread)
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index 7bdd239c795c..538db4e5d1e6 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -28,10 +28,11 @@ static int __report_module(struct addr_location *al, u64 ip,
28{ 28{
29 Dwfl_Module *mod; 29 Dwfl_Module *mod;
30 struct dso *dso = NULL; 30 struct dso *dso = NULL;
31 31 /*
32 thread__find_addr_location(ui->thread, 32 * Some callers will use al->sym, so we can't just use the
33 PERF_RECORD_MISC_USER, 33 * cheaper thread__find_map() here.
34 MAP__FUNCTION, ip, al); 34 */
35 thread__find_symbol(ui->thread, PERF_RECORD_MISC_USER, ip, al);
35 36
36 if (al->map) 37 if (al->map)
37 dso = al->map->dso; 38 dso = al->map->dso;
@@ -103,19 +104,7 @@ static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr,
103 struct addr_location al; 104 struct addr_location al;
104 ssize_t size; 105 ssize_t size;
105 106
106 thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER, 107 if (!thread__find_map(ui->thread, PERF_RECORD_MISC_USER, addr, &al)) {
107 MAP__FUNCTION, addr, &al);
108 if (!al.map) {
109 /*
110 * We've seen cases (softice) where DWARF unwinder went
111 * through non executable mmaps, which we need to lookup
112 * in MAP__VARIABLE tree.
113 */
114 thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
115 MAP__VARIABLE, addr, &al);
116 }
117
118 if (!al.map) {
119 pr_debug("unwind: no map for %lx\n", (unsigned long)addr); 108 pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
120 return -1; 109 return -1;
121 } 110 }
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index af873044d33a..6a11bc7e6b27 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -366,19 +366,7 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
366static struct map *find_map(unw_word_t ip, struct unwind_info *ui) 366static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
367{ 367{
368 struct addr_location al; 368 struct addr_location al;
369 369 return thread__find_map(ui->thread, PERF_RECORD_MISC_USER, ip, &al);
370 thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
371 MAP__FUNCTION, ip, &al);
372 if (!al.map) {
373 /*
374 * We've seen cases (softice) where DWARF unwinder went
375 * through non executable mmaps, which we need to lookup
376 * in MAP__VARIABLE tree.
377 */
378 thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
379 MAP__VARIABLE, ip, &al);
380 }
381 return al.map;
382} 370}
383 371
384static int 372static int
@@ -586,12 +574,9 @@ static int entry(u64 ip, struct thread *thread,
586 struct unwind_entry e; 574 struct unwind_entry e;
587 struct addr_location al; 575 struct addr_location al;
588 576
589 thread__find_addr_location(thread, PERF_RECORD_MISC_USER, 577 e.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
590 MAP__FUNCTION, ip, &al);
591
592 e.ip = al.addr; 578 e.ip = al.addr;
593 e.map = al.map; 579 e.map = al.map;
594 e.sym = al.sym;
595 580
596 pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", 581 pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
597 al.sym ? al.sym->name : "''", 582 al.sym ? al.sym->name : "''",
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c
index 0acb1ec0e2f0..741af209b19d 100644
--- a/tools/perf/util/vdso.c
+++ b/tools/perf/util/vdso.c
@@ -139,12 +139,10 @@ static enum dso_type machine__thread_dso_type(struct machine *machine,
139 struct thread *thread) 139 struct thread *thread)
140{ 140{
141 enum dso_type dso_type = DSO__TYPE_UNKNOWN; 141 enum dso_type dso_type = DSO__TYPE_UNKNOWN;
142 struct map *map; 142 struct map *map = map_groups__first(thread->mg);
143 struct dso *dso;
144 143
145 map = map_groups__first(thread->mg, MAP__FUNCTION);
146 for (; map ; map = map_groups__next(map)) { 144 for (; map ; map = map_groups__next(map)) {
147 dso = map->dso; 145 struct dso *dso = map->dso;
148 if (!dso || dso->long_name[0] != '/') 146 if (!dso || dso->long_name[0] != '/')
149 continue; 147 continue;
150 dso_type = dso__type(dso, machine); 148 dso_type = dso__type(dso, machine);