aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Makefile.perf1
-rw-r--r--tools/perf/arch/common.c3
-rw-r--r--tools/perf/builtin-annotate.c13
-rw-r--r--tools/perf/builtin-diff.c2
-rw-r--r--tools/perf/builtin-inject.c65
-rw-r--r--tools/perf/builtin-kvm.c6
-rw-r--r--tools/perf/builtin-mem.c5
-rw-r--r--tools/perf/builtin-probe.c17
-rw-r--r--tools/perf/builtin-record.c94
-rw-r--r--tools/perf/builtin-report.c259
-rw-r--r--tools/perf/builtin-sched.c2
-rw-r--r--tools/perf/builtin-script.c22
-rw-r--r--tools/perf/builtin-stat.c6
-rw-r--r--tools/perf/builtin-timechart.c3
-rw-r--r--tools/perf/builtin-top.c23
-rw-r--r--tools/perf/builtin-trace.c14
-rw-r--r--tools/perf/config/Makefile6
-rw-r--r--tools/perf/config/feature-checks/.gitignore2
-rw-r--r--tools/perf/config/feature-checks/Makefile110
-rw-r--r--tools/perf/config/utilities.mak7
-rw-r--r--tools/perf/perf.h2
-rw-r--r--tools/perf/tests/code-reading.c2
-rw-r--r--tools/perf/tests/keep-tracking.c2
-rw-r--r--tools/perf/tests/make38
-rw-r--r--tools/perf/tests/open-syscall-tp-fields.c2
-rw-r--r--tools/perf/tests/perf-record.c2
-rw-r--r--tools/perf/tests/perf-time-to-tsc.c2
-rw-r--r--tools/perf/ui/browser.c8
-rw-r--r--tools/perf/ui/browser.h2
-rw-r--r--tools/perf/ui/browsers/header.c127
-rw-r--r--tools/perf/ui/browsers/hists.c63
-rw-r--r--tools/perf/ui/browsers/scripts.c3
-rw-r--r--tools/perf/ui/gtk/util.c3
-rw-r--r--tools/perf/ui/stdio/hist.c2
-rw-r--r--tools/perf/ui/tui/util.c19
-rw-r--r--tools/perf/util/alias.c6
-rw-r--r--tools/perf/util/annotate.c73
-rw-r--r--tools/perf/util/annotate.h9
-rw-r--r--tools/perf/util/callchain.h2
-rw-r--r--tools/perf/util/cgroup.c2
-rw-r--r--tools/perf/util/comm.c2
-rw-r--r--tools/perf/util/debug.c1
-rw-r--r--tools/perf/util/dso.c9
-rw-r--r--tools/perf/util/event.c45
-rw-r--r--tools/perf/util/evlist.c9
-rw-r--r--tools/perf/util/evlist.h7
-rw-r--r--tools/perf/util/evsel.c17
-rw-r--r--tools/perf/util/evsel.h4
-rw-r--r--tools/perf/util/header.c15
-rw-r--r--tools/perf/util/help.c7
-rw-r--r--tools/perf/util/hist.c27
-rw-r--r--tools/perf/util/hist.h3
-rw-r--r--tools/perf/util/machine.c12
-rw-r--r--tools/perf/util/parse-events.c8
-rw-r--r--tools/perf/util/pmu.c2
-rw-r--r--tools/perf/util/probe-event.c234
-rw-r--r--tools/perf/util/probe-event.h1
-rw-r--r--tools/perf/util/probe-finder.c33
-rw-r--r--tools/perf/util/record.c9
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c22
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c28
-rw-r--r--tools/perf/util/session.c33
-rw-r--r--tools/perf/util/session.h2
-rw-r--r--tools/perf/util/sort.c22
-rw-r--r--tools/perf/util/srcline.c6
-rw-r--r--tools/perf/util/strbuf.c2
-rw-r--r--tools/perf/util/strfilter.c2
-rw-r--r--tools/perf/util/string.c2
-rw-r--r--tools/perf/util/strlist.c3
-rw-r--r--tools/perf/util/svghelper.c5
-rw-r--r--tools/perf/util/symbol-elf.c2
-rw-r--r--tools/perf/util/symbol-minimal.c3
-rw-r--r--tools/perf/util/symbol.c11
-rw-r--r--tools/perf/util/symbol.h1
-rw-r--r--tools/perf/util/thread_map.c20
-rw-r--r--tools/perf/util/top.c2
-rw-r--r--tools/perf/util/top.h2
-rw-r--r--tools/perf/util/trace-event-info.c10
-rw-r--r--tools/perf/util/trace-event-scripting.c3
-rw-r--r--tools/perf/util/trace-event.h1
-rw-r--r--tools/perf/util/util.h2
-rw-r--r--tools/perf/util/values.c14
82 files changed, 908 insertions, 764 deletions
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 97a2145e4cc6..3638b0bd20dc 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -489,6 +489,7 @@ ifndef NO_SLANG
489 LIB_OBJS += $(OUTPUT)ui/browsers/hists.o 489 LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
490 LIB_OBJS += $(OUTPUT)ui/browsers/map.o 490 LIB_OBJS += $(OUTPUT)ui/browsers/map.o
491 LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o 491 LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
492 LIB_OBJS += $(OUTPUT)ui/browsers/header.o
492 LIB_OBJS += $(OUTPUT)ui/tui/setup.o 493 LIB_OBJS += $(OUTPUT)ui/tui/setup.o
493 LIB_OBJS += $(OUTPUT)ui/tui/util.o 494 LIB_OBJS += $(OUTPUT)ui/tui/util.o
494 LIB_OBJS += $(OUTPUT)ui/tui/helpline.o 495 LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
index aacef07ebf31..42faf369211c 100644
--- a/tools/perf/arch/common.c
+++ b/tools/perf/arch/common.c
@@ -154,8 +154,7 @@ static int perf_session_env__lookup_binutils_path(struct perf_session_env *env,
154 } 154 }
155 if (lookup_path(buf)) 155 if (lookup_path(buf))
156 goto out; 156 goto out;
157 free(buf); 157 zfree(&buf);
158 buf = NULL;
159 } 158 }
160 159
161 if (!strcmp(arch, "arm")) 160 if (!strcmp(arch, "arm"))
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 6fd52c8fa682..ab65057a0317 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -69,15 +69,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
69 if (he == NULL) 69 if (he == NULL)
70 return -ENOMEM; 70 return -ENOMEM;
71 71
72 ret = 0; 72 ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
73 if (he->ms.sym != NULL) {
74 struct annotation *notes = symbol__annotation(he->ms.sym);
75 if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0)
76 return -ENOMEM;
77
78 ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
79 }
80
81 evsel->hists.stats.total_period += sample->period; 73 evsel->hists.stats.total_period += sample->period;
82 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); 74 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
83 return ret; 75 return ret;
@@ -188,8 +180,7 @@ find_next:
188 * symbol, free he->ms.sym->src to signal we already 180 * symbol, free he->ms.sym->src to signal we already
189 * processed this symbol. 181 * processed this symbol.
190 */ 182 */
191 free(notes->src); 183 zfree(&notes->src);
192 notes->src = NULL;
193 } 184 }
194 } 185 }
195} 186}
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 2a85cc9a2d09..e6a0844bc2f0 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -654,7 +654,7 @@ static void data__free(struct data__file *d)
654 for (col = 0; col < PERF_HPP_DIFF__MAX_INDEX; col++) { 654 for (col = 0; col < PERF_HPP_DIFF__MAX_INDEX; col++) {
655 struct diff_hpp_fmt *fmt = &d->fmt[col]; 655 struct diff_hpp_fmt *fmt = &d->fmt[col];
656 656
657 free(fmt->header); 657 zfree(&fmt->header);
658 } 658 }
659} 659}
660 660
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 6a2508589460..c9f6d74e1fd7 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -22,14 +22,13 @@
22#include <linux/list.h> 22#include <linux/list.h>
23 23
24struct perf_inject { 24struct perf_inject {
25 struct perf_tool tool; 25 struct perf_tool tool;
26 bool build_ids; 26 bool build_ids;
27 bool sched_stat; 27 bool sched_stat;
28 const char *input_name; 28 const char *input_name;
29 int pipe_output, 29 struct perf_data_file output;
30 output; 30 u64 bytes_written;
31 u64 bytes_written; 31 struct list_head samples;
32 struct list_head samples;
33}; 32};
34 33
35struct event_entry { 34struct event_entry {
@@ -42,21 +41,14 @@ static int perf_event__repipe_synth(struct perf_tool *tool,
42 union perf_event *event) 41 union perf_event *event)
43{ 42{
44 struct perf_inject *inject = container_of(tool, struct perf_inject, tool); 43 struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
45 uint32_t size; 44 ssize_t size;
46 void *buf = event;
47 45
48 size = event->header.size; 46 size = perf_data_file__write(&inject->output, event,
49 47 event->header.size);
50 while (size) { 48 if (size < 0)
51 int ret = write(inject->output, buf, size); 49 return -errno;
52 if (ret < 0)
53 return -errno;
54
55 size -= ret;
56 buf += ret;
57 inject->bytes_written += ret;
58 }
59 50
51 inject->bytes_written += size;
60 return 0; 52 return 0;
61} 53}
62 54
@@ -80,7 +72,7 @@ static int perf_event__repipe_attr(struct perf_tool *tool,
80 if (ret) 72 if (ret)
81 return ret; 73 return ret;
82 74
83 if (!inject->pipe_output) 75 if (&inject->output.is_pipe)
84 return 0; 76 return 0;
85 77
86 return perf_event__repipe_synth(tool, event); 78 return perf_event__repipe_synth(tool, event);
@@ -355,6 +347,7 @@ static int __cmd_inject(struct perf_inject *inject)
355 .path = inject->input_name, 347 .path = inject->input_name,
356 .mode = PERF_DATA_MODE_READ, 348 .mode = PERF_DATA_MODE_READ,
357 }; 349 };
350 struct perf_data_file *file_out = &inject->output;
358 351
359 signal(SIGINT, sig_handler); 352 signal(SIGINT, sig_handler);
360 353
@@ -391,14 +384,14 @@ static int __cmd_inject(struct perf_inject *inject)
391 } 384 }
392 } 385 }
393 386
394 if (!inject->pipe_output) 387 if (!file_out->is_pipe)
395 lseek(inject->output, session->header.data_offset, SEEK_SET); 388 lseek(file_out->fd, session->header.data_offset, SEEK_SET);
396 389
397 ret = perf_session__process_events(session, &inject->tool); 390 ret = perf_session__process_events(session, &inject->tool);
398 391
399 if (!inject->pipe_output) { 392 if (!file_out->is_pipe) {
400 session->header.data_size = inject->bytes_written; 393 session->header.data_size = inject->bytes_written;
401 perf_session__write_header(session, session->evlist, inject->output, true); 394 perf_session__write_header(session, session->evlist, file_out->fd, true);
402 } 395 }
403 396
404 perf_session__delete(session); 397 perf_session__delete(session);
@@ -427,14 +420,17 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
427 }, 420 },
428 .input_name = "-", 421 .input_name = "-",
429 .samples = LIST_HEAD_INIT(inject.samples), 422 .samples = LIST_HEAD_INIT(inject.samples),
423 .output = {
424 .path = "-",
425 .mode = PERF_DATA_MODE_WRITE,
426 },
430 }; 427 };
431 const char *output_name = "-";
432 const struct option options[] = { 428 const struct option options[] = {
433 OPT_BOOLEAN('b', "build-ids", &inject.build_ids, 429 OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
434 "Inject build-ids into the output stream"), 430 "Inject build-ids into the output stream"),
435 OPT_STRING('i', "input", &inject.input_name, "file", 431 OPT_STRING('i', "input", &inject.input_name, "file",
436 "input file name"), 432 "input file name"),
437 OPT_STRING('o', "output", &output_name, "file", 433 OPT_STRING('o', "output", &inject.output.path, "file",
438 "output file name"), 434 "output file name"),
439 OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, 435 OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat,
440 "Merge sched-stat and sched-switch for getting events " 436 "Merge sched-stat and sched-switch for getting events "
@@ -456,16 +452,9 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
456 if (argc) 452 if (argc)
457 usage_with_options(inject_usage, options); 453 usage_with_options(inject_usage, options);
458 454
459 if (!strcmp(output_name, "-")) { 455 if (perf_data_file__open(&inject.output)) {
460 inject.pipe_output = 1; 456 perror("failed to create output file");
461 inject.output = STDOUT_FILENO; 457 return -1;
462 } else {
463 inject.output = open(output_name, O_CREAT | O_WRONLY | O_TRUNC,
464 S_IRUSR | S_IWUSR);
465 if (inject.output < 0) {
466 perror("failed to create output file");
467 return -1;
468 }
469 } 458 }
470 459
471 if (symbol__init() < 0) 460 if (symbol__init() < 0)
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 154b397a5d27..a6ec1052c291 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -89,7 +89,7 @@ struct exit_reasons_table {
89 89
90struct perf_kvm_stat { 90struct perf_kvm_stat {
91 struct perf_tool tool; 91 struct perf_tool tool;
92 struct perf_record_opts opts; 92 struct record_opts opts;
93 struct perf_evlist *evlist; 93 struct perf_evlist *evlist;
94 struct perf_session *session; 94 struct perf_session *session;
95 95
@@ -1158,9 +1158,7 @@ out:
1158 if (kvm->timerfd >= 0) 1158 if (kvm->timerfd >= 0)
1159 close(kvm->timerfd); 1159 close(kvm->timerfd);
1160 1160
1161 if (pollfds) 1161 free(pollfds);
1162 free(pollfds);
1163
1164 return err; 1162 return err;
1165} 1163}
1166 1164
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 31c00f186da1..2e3ade69a58e 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -62,7 +62,6 @@ static int
62dump_raw_samples(struct perf_tool *tool, 62dump_raw_samples(struct perf_tool *tool,
63 union perf_event *event, 63 union perf_event *event,
64 struct perf_sample *sample, 64 struct perf_sample *sample,
65 struct perf_evsel *evsel __maybe_unused,
66 struct machine *machine) 65 struct machine *machine)
67{ 66{
68 struct perf_mem *mem = container_of(tool, struct perf_mem, tool); 67 struct perf_mem *mem = container_of(tool, struct perf_mem, tool);
@@ -112,10 +111,10 @@ dump_raw_samples(struct perf_tool *tool,
112static int process_sample_event(struct perf_tool *tool, 111static int process_sample_event(struct perf_tool *tool,
113 union perf_event *event, 112 union perf_event *event,
114 struct perf_sample *sample, 113 struct perf_sample *sample,
115 struct perf_evsel *evsel, 114 struct perf_evsel *evsel __maybe_unused,
116 struct machine *machine) 115 struct machine *machine)
117{ 116{
118 return dump_raw_samples(tool, event, sample, evsel, machine); 117 return dump_raw_samples(tool, event, sample, machine);
119} 118}
120 119
121static int report_raw_events(struct perf_mem *mem) 120static int report_raw_events(struct perf_mem *mem)
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index c98ccb570509..43ff33d0007b 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -169,6 +169,7 @@ static int opt_set_target(const struct option *opt, const char *str,
169 int unset __maybe_unused) 169 int unset __maybe_unused)
170{ 170{
171 int ret = -ENOENT; 171 int ret = -ENOENT;
172 char *tmp;
172 173
173 if (str && !params.target) { 174 if (str && !params.target) {
174 if (!strcmp(opt->long_name, "exec")) 175 if (!strcmp(opt->long_name, "exec"))
@@ -180,7 +181,19 @@ static int opt_set_target(const struct option *opt, const char *str,
180 else 181 else
181 return ret; 182 return ret;
182 183
183 params.target = str; 184 /* Expand given path to absolute path, except for modulename */
185 if (params.uprobes || strchr(str, '/')) {
186 tmp = realpath(str, NULL);
187 if (!tmp) {
188 pr_warning("Failed to get the absolute path of %s: %m\n", str);
189 return ret;
190 }
191 } else {
192 tmp = strdup(str);
193 if (!tmp)
194 return -ENOMEM;
195 }
196 params.target = tmp;
184 ret = 0; 197 ret = 0;
185 } 198 }
186 199
@@ -411,7 +424,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
411 } 424 }
412 425
413#ifdef HAVE_DWARF_SUPPORT 426#ifdef HAVE_DWARF_SUPPORT
414 if (params.show_lines && !params.uprobes) { 427 if (params.show_lines) {
415 if (params.mod_events) { 428 if (params.mod_events) {
416 pr_err(" Error: Don't use --line with" 429 pr_err(" Error: Don't use --line with"
417 " --add/--del.\n"); 430 " --add/--del.\n");
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index c1c1200d2f0a..6ec0cbc2a5d5 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -62,9 +62,9 @@ static void __handle_on_exit_funcs(void)
62} 62}
63#endif 63#endif
64 64
65struct perf_record { 65struct record {
66 struct perf_tool tool; 66 struct perf_tool tool;
67 struct perf_record_opts opts; 67 struct record_opts opts;
68 u64 bytes_written; 68 u64 bytes_written;
69 struct perf_data_file file; 69 struct perf_data_file file;
70 struct perf_evlist *evlist; 70 struct perf_evlist *evlist;
@@ -76,24 +76,14 @@ struct perf_record {
76 long samples; 76 long samples;
77}; 77};
78 78
79static int perf_record__write(struct perf_record *rec, void *buf, size_t size) 79static int record__write(struct record *rec, void *bf, size_t size)
80{ 80{
81 struct perf_data_file *file = &rec->file; 81 if (perf_data_file__write(rec->session->file, bf, size) < 0) {
82 82 pr_err("failed to write perf data, error: %m\n");
83 while (size) { 83 return -1;
84 ssize_t ret = write(file->fd, buf, size);
85
86 if (ret < 0) {
87 pr_err("failed to write perf data, error: %m\n");
88 return -1;
89 }
90
91 size -= ret;
92 buf += ret;
93
94 rec->bytes_written += ret;
95 } 84 }
96 85
86 rec->bytes_written += size;
97 return 0; 87 return 0;
98} 88}
99 89
@@ -102,12 +92,11 @@ static int process_synthesized_event(struct perf_tool *tool,
102 struct perf_sample *sample __maybe_unused, 92 struct perf_sample *sample __maybe_unused,
103 struct machine *machine __maybe_unused) 93 struct machine *machine __maybe_unused)
104{ 94{
105 struct perf_record *rec = container_of(tool, struct perf_record, tool); 95 struct record *rec = container_of(tool, struct record, tool);
106 return perf_record__write(rec, event, event->header.size); 96 return record__write(rec, event, event->header.size);
107} 97}
108 98
109static int perf_record__mmap_read(struct perf_record *rec, 99static int record__mmap_read(struct record *rec, struct perf_mmap *md)
110 struct perf_mmap *md)
111{ 100{
112 unsigned int head = perf_mmap__read_head(md); 101 unsigned int head = perf_mmap__read_head(md);
113 unsigned int old = md->prev; 102 unsigned int old = md->prev;
@@ -128,7 +117,7 @@ static int perf_record__mmap_read(struct perf_record *rec,
128 size = md->mask + 1 - (old & md->mask); 117 size = md->mask + 1 - (old & md->mask);
129 old += size; 118 old += size;
130 119
131 if (perf_record__write(rec, buf, size) < 0) { 120 if (record__write(rec, buf, size) < 0) {
132 rc = -1; 121 rc = -1;
133 goto out; 122 goto out;
134 } 123 }
@@ -138,7 +127,7 @@ static int perf_record__mmap_read(struct perf_record *rec,
138 size = head - old; 127 size = head - old;
139 old += size; 128 old += size;
140 129
141 if (perf_record__write(rec, buf, size) < 0) { 130 if (record__write(rec, buf, size) < 0) {
142 rc = -1; 131 rc = -1;
143 goto out; 132 goto out;
144 } 133 }
@@ -163,9 +152,9 @@ static void sig_handler(int sig)
163 signr = sig; 152 signr = sig;
164} 153}
165 154
166static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg) 155static void record__sig_exit(int exit_status __maybe_unused, void *arg)
167{ 156{
168 struct perf_record *rec = arg; 157 struct record *rec = arg;
169 int status; 158 int status;
170 159
171 if (rec->evlist->workload.pid > 0) { 160 if (rec->evlist->workload.pid > 0) {
@@ -183,13 +172,13 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
183 signal(signr, SIG_DFL); 172 signal(signr, SIG_DFL);
184} 173}
185 174
186static int perf_record__open(struct perf_record *rec) 175static int record__open(struct record *rec)
187{ 176{
188 char msg[512]; 177 char msg[512];
189 struct perf_evsel *pos; 178 struct perf_evsel *pos;
190 struct perf_evlist *evlist = rec->evlist; 179 struct perf_evlist *evlist = rec->evlist;
191 struct perf_session *session = rec->session; 180 struct perf_session *session = rec->session;
192 struct perf_record_opts *opts = &rec->opts; 181 struct record_opts *opts = &rec->opts;
193 int rc = 0; 182 int rc = 0;
194 183
195 perf_evlist__config(evlist, opts); 184 perf_evlist__config(evlist, opts);
@@ -239,7 +228,7 @@ out:
239 return rc; 228 return rc;
240} 229}
241 230
242static int process_buildids(struct perf_record *rec) 231static int process_buildids(struct record *rec)
243{ 232{
244 struct perf_data_file *file = &rec->file; 233 struct perf_data_file *file = &rec->file;
245 struct perf_session *session = rec->session; 234 struct perf_session *session = rec->session;
@@ -254,9 +243,9 @@ static int process_buildids(struct perf_record *rec)
254 size, &build_id__mark_dso_hit_ops); 243 size, &build_id__mark_dso_hit_ops);
255} 244}
256 245
257static void perf_record__exit(int status, void *arg) 246static void record__exit(int status, void *arg)
258{ 247{
259 struct perf_record *rec = arg; 248 struct record *rec = arg;
260 struct perf_data_file *file = &rec->file; 249 struct perf_data_file *file = &rec->file;
261 250
262 if (status != 0) 251 if (status != 0)
@@ -312,14 +301,14 @@ static struct perf_event_header finished_round_event = {
312 .type = PERF_RECORD_FINISHED_ROUND, 301 .type = PERF_RECORD_FINISHED_ROUND,
313}; 302};
314 303
315static int perf_record__mmap_read_all(struct perf_record *rec) 304static int record__mmap_read_all(struct record *rec)
316{ 305{
317 int i; 306 int i;
318 int rc = 0; 307 int rc = 0;
319 308
320 for (i = 0; i < rec->evlist->nr_mmaps; i++) { 309 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
321 if (rec->evlist->mmap[i].base) { 310 if (rec->evlist->mmap[i].base) {
322 if (perf_record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) { 311 if (record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) {
323 rc = -1; 312 rc = -1;
324 goto out; 313 goto out;
325 } 314 }
@@ -327,14 +316,13 @@ static int perf_record__mmap_read_all(struct perf_record *rec)
327 } 316 }
328 317
329 if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) 318 if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA))
330 rc = perf_record__write(rec, &finished_round_event, 319 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
331 sizeof(finished_round_event));
332 320
333out: 321out:
334 return rc; 322 return rc;
335} 323}
336 324
337static void perf_record__init_features(struct perf_record *rec) 325static void record__init_features(struct record *rec)
338{ 326{
339 struct perf_evlist *evsel_list = rec->evlist; 327 struct perf_evlist *evsel_list = rec->evlist;
340 struct perf_session *session = rec->session; 328 struct perf_session *session = rec->session;
@@ -353,14 +341,14 @@ static void perf_record__init_features(struct perf_record *rec)
353 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 341 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
354} 342}
355 343
356static int __cmd_record(struct perf_record *rec, int argc, const char **argv) 344static int __cmd_record(struct record *rec, int argc, const char **argv)
357{ 345{
358 int err; 346 int err;
359 unsigned long waking = 0; 347 unsigned long waking = 0;
360 const bool forks = argc > 0; 348 const bool forks = argc > 0;
361 struct machine *machine; 349 struct machine *machine;
362 struct perf_tool *tool = &rec->tool; 350 struct perf_tool *tool = &rec->tool;
363 struct perf_record_opts *opts = &rec->opts; 351 struct record_opts *opts = &rec->opts;
364 struct perf_evlist *evsel_list = rec->evlist; 352 struct perf_evlist *evsel_list = rec->evlist;
365 struct perf_data_file *file = &rec->file; 353 struct perf_data_file *file = &rec->file;
366 struct perf_session *session; 354 struct perf_session *session;
@@ -368,7 +356,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
368 356
369 rec->progname = argv[0]; 357 rec->progname = argv[0];
370 358
371 on_exit(perf_record__sig_exit, rec); 359 on_exit(record__sig_exit, rec);
372 signal(SIGCHLD, sig_handler); 360 signal(SIGCHLD, sig_handler);
373 signal(SIGINT, sig_handler); 361 signal(SIGINT, sig_handler);
374 signal(SIGUSR1, sig_handler); 362 signal(SIGUSR1, sig_handler);
@@ -382,7 +370,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
382 370
383 rec->session = session; 371 rec->session = session;
384 372
385 perf_record__init_features(rec); 373 record__init_features(rec);
386 374
387 if (forks) { 375 if (forks) {
388 err = perf_evlist__prepare_workload(evsel_list, &opts->target, 376 err = perf_evlist__prepare_workload(evsel_list, &opts->target,
@@ -394,7 +382,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
394 } 382 }
395 } 383 }
396 384
397 if (perf_record__open(rec) != 0) { 385 if (record__open(rec) != 0) {
398 err = -1; 386 err = -1;
399 goto out_delete_session; 387 goto out_delete_session;
400 } 388 }
@@ -403,9 +391,9 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
403 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); 391 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
404 392
405 /* 393 /*
406 * perf_session__delete(session) will be called at perf_record__exit() 394 * perf_session__delete(session) will be called at record__exit()
407 */ 395 */
408 on_exit(perf_record__exit, rec); 396 on_exit(record__exit, rec);
409 397
410 if (file->is_pipe) { 398 if (file->is_pipe) {
411 err = perf_header__write_pipe(file->fd); 399 err = perf_header__write_pipe(file->fd);
@@ -510,7 +498,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
510 for (;;) { 498 for (;;) {
511 int hits = rec->samples; 499 int hits = rec->samples;
512 500
513 if (perf_record__mmap_read_all(rec) < 0) { 501 if (record__mmap_read_all(rec) < 0) {
514 err = -1; 502 err = -1;
515 goto out_delete_session; 503 goto out_delete_session;
516 } 504 }
@@ -669,7 +657,7 @@ static int get_stack_size(char *str, unsigned long *_size)
669} 657}
670#endif /* HAVE_LIBUNWIND_SUPPORT */ 658#endif /* HAVE_LIBUNWIND_SUPPORT */
671 659
672int record_parse_callchain(const char *arg, struct perf_record_opts *opts) 660int record_parse_callchain(const char *arg, struct record_opts *opts)
673{ 661{
674 char *tok, *name, *saveptr = NULL; 662 char *tok, *name, *saveptr = NULL;
675 char *buf; 663 char *buf;
@@ -725,7 +713,7 @@ int record_parse_callchain(const char *arg, struct perf_record_opts *opts)
725 return ret; 713 return ret;
726} 714}
727 715
728static void callchain_debug(struct perf_record_opts *opts) 716static void callchain_debug(struct record_opts *opts)
729{ 717{
730 pr_debug("callchain: type %d\n", opts->call_graph); 718 pr_debug("callchain: type %d\n", opts->call_graph);
731 719
@@ -738,7 +726,7 @@ int record_parse_callchain_opt(const struct option *opt,
738 const char *arg, 726 const char *arg,
739 int unset) 727 int unset)
740{ 728{
741 struct perf_record_opts *opts = opt->value; 729 struct record_opts *opts = opt->value;
742 int ret; 730 int ret;
743 731
744 /* --no-call-graph */ 732 /* --no-call-graph */
@@ -759,7 +747,7 @@ int record_callchain_opt(const struct option *opt,
759 const char *arg __maybe_unused, 747 const char *arg __maybe_unused,
760 int unset __maybe_unused) 748 int unset __maybe_unused)
761{ 749{
762 struct perf_record_opts *opts = opt->value; 750 struct record_opts *opts = opt->value;
763 751
764 if (opts->call_graph == CALLCHAIN_NONE) 752 if (opts->call_graph == CALLCHAIN_NONE)
765 opts->call_graph = CALLCHAIN_FP; 753 opts->call_graph = CALLCHAIN_FP;
@@ -775,8 +763,8 @@ static const char * const record_usage[] = {
775}; 763};
776 764
777/* 765/*
778 * XXX Ideally would be local to cmd_record() and passed to a perf_record__new 766 * XXX Ideally would be local to cmd_record() and passed to a record__new
779 * because we need to have access to it in perf_record__exit, that is called 767 * because we need to have access to it in record__exit, that is called
780 * after cmd_record() exits, but since record_options need to be accessible to 768 * after cmd_record() exits, but since record_options need to be accessible to
781 * builtin-script, leave it here. 769 * builtin-script, leave it here.
782 * 770 *
@@ -784,7 +772,7 @@ static const char * const record_usage[] = {
784 * 772 *
785 * Just say no to tons of global variables, sigh. 773 * Just say no to tons of global variables, sigh.
786 */ 774 */
787static struct perf_record record = { 775static struct record record = {
788 .opts = { 776 .opts = {
789 .mmap_pages = UINT_MAX, 777 .mmap_pages = UINT_MAX,
790 .user_freq = UINT_MAX, 778 .user_freq = UINT_MAX,
@@ -808,7 +796,7 @@ const char record_callchain_help[] = CALLCHAIN_HELP "fp";
808/* 796/*
809 * XXX Will stay a global variable till we fix builtin-script.c to stop messing 797 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
810 * with it and switch to use the library functions in perf_evlist that came 798 * with it and switch to use the library functions in perf_evlist that came
811 * from builtin-record.c, i.e. use perf_record_opts, 799 * from builtin-record.c, i.e. use record_opts,
812 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record', 800 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
813 * using pipes, etc. 801 * using pipes, etc.
814 */ 802 */
@@ -891,7 +879,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
891{ 879{
892 int err = -ENOMEM; 880 int err = -ENOMEM;
893 struct perf_evlist *evsel_list; 881 struct perf_evlist *evsel_list;
894 struct perf_record *rec = &record; 882 struct record *rec = &record;
895 char errbuf[BUFSIZ]; 883 char errbuf[BUFSIZ];
896 884
897 evsel_list = perf_evlist__new(); 885 evsel_list = perf_evlist__new();
@@ -956,7 +944,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
956 if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0) 944 if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
957 usage_with_options(record_usage, record_options); 945 usage_with_options(record_usage, record_options);
958 946
959 if (perf_record_opts__config(&rec->opts)) { 947 if (record_opts__config(&rec->opts)) {
960 err = -EINVAL; 948 err = -EINVAL;
961 goto out_free_fd; 949 goto out_free_fd;
962 } 950 }
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 3a14dbed387c..bf8dd2e893e4 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -39,7 +39,7 @@
39#include <dlfcn.h> 39#include <dlfcn.h>
40#include <linux/bitmap.h> 40#include <linux/bitmap.h>
41 41
42struct perf_report { 42struct report {
43 struct perf_tool tool; 43 struct perf_tool tool;
44 struct perf_session *session; 44 struct perf_session *session;
45 bool force, use_tui, use_gtk, use_stdio; 45 bool force, use_tui, use_gtk, use_stdio;
@@ -60,14 +60,14 @@ struct perf_report {
60 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 60 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
61}; 61};
62 62
63static int perf_report_config(const char *var, const char *value, void *cb) 63static int report__config(const char *var, const char *value, void *cb)
64{ 64{
65 if (!strcmp(var, "report.group")) { 65 if (!strcmp(var, "report.group")) {
66 symbol_conf.event_group = perf_config_bool(var, value); 66 symbol_conf.event_group = perf_config_bool(var, value);
67 return 0; 67 return 0;
68 } 68 }
69 if (!strcmp(var, "report.percent-limit")) { 69 if (!strcmp(var, "report.percent-limit")) {
70 struct perf_report *rep = cb; 70 struct report *rep = cb;
71 rep->min_percent = strtof(value, NULL); 71 rep->min_percent = strtof(value, NULL);
72 return 0; 72 return 0;
73 } 73 }
@@ -75,31 +75,40 @@ static int perf_report_config(const char *var, const char *value, void *cb)
75 return perf_default_config(var, value, cb); 75 return perf_default_config(var, value, cb);
76} 76}
77 77
78static int perf_report__add_mem_hist_entry(struct perf_tool *tool, 78static int report__resolve_callchain(struct report *rep, struct symbol **parent,
79 struct addr_location *al, 79 struct perf_evsel *evsel, struct addr_location *al,
80 struct perf_sample *sample, 80 struct perf_sample *sample)
81 struct perf_evsel *evsel,
82 struct machine *machine,
83 union perf_event *event)
84{ 81{
85 struct perf_report *rep = container_of(tool, struct perf_report, tool); 82 if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) {
83 return machine__resolve_callchain(al->machine, evsel, al->thread, sample,
84 parent, al, rep->max_stack);
85 }
86 return 0;
87}
88
89static int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample)
90{
91 if (!symbol_conf.use_callchain)
92 return 0;
93 return callchain_append(he->callchain, &callchain_cursor, sample->period);
94}
95
96static int report__add_mem_hist_entry(struct perf_tool *tool, struct addr_location *al,
97 struct perf_sample *sample, struct perf_evsel *evsel,
98 union perf_event *event)
99{
100 struct report *rep = container_of(tool, struct report, tool);
86 struct symbol *parent = NULL; 101 struct symbol *parent = NULL;
87 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 102 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
88 int err = 0;
89 struct hist_entry *he; 103 struct hist_entry *he;
90 struct mem_info *mi, *mx; 104 struct mem_info *mi, *mx;
91 uint64_t cost; 105 uint64_t cost;
106 int err = report__resolve_callchain(rep, &parent, evsel, al, sample);
92 107
93 if ((sort__has_parent || symbol_conf.use_callchain) && 108 if (err)
94 sample->callchain) { 109 return err;
95 err = machine__resolve_callchain(machine, evsel, al->thread,
96 sample, &parent, al,
97 rep->max_stack);
98 if (err)
99 return err;
100 }
101 110
102 mi = machine__resolve_mem(machine, al->thread, sample, cpumode); 111 mi = machine__resolve_mem(al->machine, al->thread, sample, cpumode);
103 if (!mi) 112 if (!mi)
104 return -ENOMEM; 113 return -ENOMEM;
105 114
@@ -122,77 +131,36 @@ static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
122 if (!he) 131 if (!he)
123 return -ENOMEM; 132 return -ENOMEM;
124 133
125 /* 134 err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
126 * In the TUI browser, we are doing integrated annotation, 135 if (err)
127 * so we don't allocate the extra space needed because the stdio 136 goto out;
128 * code will not use it.
129 */
130 if (sort__has_sym && he->ms.sym && use_browser > 0) {
131 struct annotation *notes = symbol__annotation(he->ms.sym);
132
133 assert(evsel != NULL);
134
135 if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0)
136 goto out;
137
138 err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
139 if (err)
140 goto out;
141 }
142
143 if (sort__has_sym && he->mem_info->daddr.sym && use_browser > 0) {
144 struct annotation *notes;
145
146 mx = he->mem_info;
147 137
148 notes = symbol__annotation(mx->daddr.sym); 138 mx = he->mem_info;
149 if (notes->src == NULL && symbol__alloc_hist(mx->daddr.sym) < 0) 139 err = addr_map_symbol__inc_samples(&mx->daddr, evsel->idx);
150 goto out; 140 if (err)
151 141 goto out;
152 err = symbol__inc_addr_samples(mx->daddr.sym,
153 mx->daddr.map,
154 evsel->idx,
155 mx->daddr.al_addr);
156 if (err)
157 goto out;
158 }
159 142
160 evsel->hists.stats.total_period += cost; 143 evsel->hists.stats.total_period += cost;
161 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); 144 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
162 err = 0; 145 err = hist_entry__append_callchain(he, sample);
163
164 if (symbol_conf.use_callchain) {
165 err = callchain_append(he->callchain,
166 &callchain_cursor,
167 sample->period);
168 }
169out: 146out:
170 return err; 147 return err;
171} 148}
172 149
173static int perf_report__add_branch_hist_entry(struct perf_tool *tool, 150static int report__add_branch_hist_entry(struct perf_tool *tool, struct addr_location *al,
174 struct addr_location *al, 151 struct perf_sample *sample, struct perf_evsel *evsel)
175 struct perf_sample *sample,
176 struct perf_evsel *evsel,
177 struct machine *machine)
178{ 152{
179 struct perf_report *rep = container_of(tool, struct perf_report, tool); 153 struct report *rep = container_of(tool, struct report, tool);
180 struct symbol *parent = NULL; 154 struct symbol *parent = NULL;
181 int err = 0;
182 unsigned i; 155 unsigned i;
183 struct hist_entry *he; 156 struct hist_entry *he;
184 struct branch_info *bi, *bx; 157 struct branch_info *bi, *bx;
158 int err = report__resolve_callchain(rep, &parent, evsel, al, sample);
185 159
186 if ((sort__has_parent || symbol_conf.use_callchain) 160 if (err)
187 && sample->callchain) { 161 return err;
188 err = machine__resolve_callchain(machine, evsel, al->thread,
189 sample, &parent, al,
190 rep->max_stack);
191 if (err)
192 return err;
193 }
194 162
195 bi = machine__resolve_bstack(machine, al->thread, 163 bi = machine__resolve_bstack(al->machine, al->thread,
196 sample->branch_stack); 164 sample->branch_stack);
197 if (!bi) 165 if (!bi)
198 return -ENOMEM; 166 return -ENOMEM;
@@ -214,35 +182,15 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
214 he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL, 182 he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL,
215 1, 1, 0); 183 1, 1, 0);
216 if (he) { 184 if (he) {
217 struct annotation *notes;
218 bx = he->branch_info; 185 bx = he->branch_info;
219 if (bx->from.sym && use_browser == 1 && sort__has_sym) { 186 err = addr_map_symbol__inc_samples(&bx->from, evsel->idx);
220 notes = symbol__annotation(bx->from.sym); 187 if (err)
221 if (!notes->src 188 goto out;
222 && symbol__alloc_hist(bx->from.sym) < 0) 189
223 goto out; 190 err = addr_map_symbol__inc_samples(&bx->to, evsel->idx);
224 191 if (err)
225 err = symbol__inc_addr_samples(bx->from.sym, 192 goto out;
226 bx->from.map,
227 evsel->idx,
228 bx->from.al_addr);
229 if (err)
230 goto out;
231 }
232 193
233 if (bx->to.sym && use_browser == 1 && sort__has_sym) {
234 notes = symbol__annotation(bx->to.sym);
235 if (!notes->src
236 && symbol__alloc_hist(bx->to.sym) < 0)
237 goto out;
238
239 err = symbol__inc_addr_samples(bx->to.sym,
240 bx->to.map,
241 evsel->idx,
242 bx->to.al_addr);
243 if (err)
244 goto out;
245 }
246 evsel->hists.stats.total_period += 1; 194 evsel->hists.stats.total_period += 1;
247 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); 195 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
248 } else 196 } else
@@ -254,24 +202,16 @@ out:
254 return err; 202 return err;
255} 203}
256 204
257static int perf_evsel__add_hist_entry(struct perf_tool *tool, 205static int report__add_hist_entry(struct perf_tool *tool, struct perf_evsel *evsel,
258 struct perf_evsel *evsel, 206 struct addr_location *al, struct perf_sample *sample)
259 struct addr_location *al,
260 struct perf_sample *sample,
261 struct machine *machine)
262{ 207{
263 struct perf_report *rep = container_of(tool, struct perf_report, tool); 208 struct report *rep = container_of(tool, struct report, tool);
264 struct symbol *parent = NULL; 209 struct symbol *parent = NULL;
265 int err = 0;
266 struct hist_entry *he; 210 struct hist_entry *he;
211 int err = report__resolve_callchain(rep, &parent, evsel, al, sample);
267 212
268 if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { 213 if (err)
269 err = machine__resolve_callchain(machine, evsel, al->thread, 214 return err;
270 sample, &parent, al,
271 rep->max_stack);
272 if (err)
273 return err;
274 }
275 215
276 he = __hists__add_entry(&evsel->hists, al, parent, NULL, NULL, 216 he = __hists__add_entry(&evsel->hists, al, parent, NULL, NULL,
277 sample->period, sample->weight, 217 sample->period, sample->weight,
@@ -279,30 +219,11 @@ static int perf_evsel__add_hist_entry(struct perf_tool *tool,
279 if (he == NULL) 219 if (he == NULL)
280 return -ENOMEM; 220 return -ENOMEM;
281 221
282 if (symbol_conf.use_callchain) { 222 err = hist_entry__append_callchain(he, sample);
283 err = callchain_append(he->callchain, 223 if (err)
284 &callchain_cursor, 224 goto out;
285 sample->period);
286 if (err)
287 return err;
288 }
289 /*
290 * Only in the TUI browser we are doing integrated annotation,
291 * so we don't allocated the extra space needed because the stdio
292 * code will not use it.
293 */
294 if (he->ms.sym != NULL && use_browser == 1 && sort__has_sym) {
295 struct annotation *notes = symbol__annotation(he->ms.sym);
296
297 assert(evsel != NULL);
298
299 err = -ENOMEM;
300 if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0)
301 goto out;
302
303 err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
304 }
305 225
226 err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
306 evsel->hists.stats.total_period += sample->period; 227 evsel->hists.stats.total_period += sample->period;
307 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); 228 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
308out: 229out:
@@ -316,13 +237,13 @@ static int process_sample_event(struct perf_tool *tool,
316 struct perf_evsel *evsel, 237 struct perf_evsel *evsel,
317 struct machine *machine) 238 struct machine *machine)
318{ 239{
319 struct perf_report *rep = container_of(tool, struct perf_report, tool); 240 struct report *rep = container_of(tool, struct report, tool);
320 struct addr_location al; 241 struct addr_location al;
321 int ret; 242 int ret;
322 243
323 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 244 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
324 fprintf(stderr, "problem processing %d event, skipping it.\n", 245 pr_debug("problem processing %d event, skipping it.\n",
325 event->header.type); 246 event->header.type);
326 return -1; 247 return -1;
327 } 248 }
328 249
@@ -333,21 +254,18 @@ static int process_sample_event(struct perf_tool *tool,
333 return 0; 254 return 0;
334 255
335 if (sort__mode == SORT_MODE__BRANCH) { 256 if (sort__mode == SORT_MODE__BRANCH) {
336 ret = perf_report__add_branch_hist_entry(tool, &al, sample, 257 ret = report__add_branch_hist_entry(tool, &al, sample, evsel);
337 evsel, machine);
338 if (ret < 0) 258 if (ret < 0)
339 pr_debug("problem adding lbr entry, skipping event\n"); 259 pr_debug("problem adding lbr entry, skipping event\n");
340 } else if (rep->mem_mode == 1) { 260 } else if (rep->mem_mode == 1) {
341 ret = perf_report__add_mem_hist_entry(tool, &al, sample, 261 ret = report__add_mem_hist_entry(tool, &al, sample, evsel, event);
342 evsel, machine, event);
343 if (ret < 0) 262 if (ret < 0)
344 pr_debug("problem adding mem entry, skipping event\n"); 263 pr_debug("problem adding mem entry, skipping event\n");
345 } else { 264 } else {
346 if (al.map != NULL) 265 if (al.map != NULL)
347 al.map->dso->hit = 1; 266 al.map->dso->hit = 1;
348 267
349 ret = perf_evsel__add_hist_entry(tool, evsel, &al, sample, 268 ret = report__add_hist_entry(tool, evsel, &al, sample);
350 machine);
351 if (ret < 0) 269 if (ret < 0)
352 pr_debug("problem incrementing symbol period, skipping event\n"); 270 pr_debug("problem incrementing symbol period, skipping event\n");
353 } 271 }
@@ -360,7 +278,7 @@ static int process_read_event(struct perf_tool *tool,
360 struct perf_evsel *evsel, 278 struct perf_evsel *evsel,
361 struct machine *machine __maybe_unused) 279 struct machine *machine __maybe_unused)
362{ 280{
363 struct perf_report *rep = container_of(tool, struct perf_report, tool); 281 struct report *rep = container_of(tool, struct report, tool);
364 282
365 if (rep->show_threads) { 283 if (rep->show_threads) {
366 const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; 284 const char *name = evsel ? perf_evsel__name(evsel) : "unknown";
@@ -379,7 +297,7 @@ static int process_read_event(struct perf_tool *tool,
379} 297}
380 298
381/* For pipe mode, sample_type is not currently set */ 299/* For pipe mode, sample_type is not currently set */
382static int perf_report__setup_sample_type(struct perf_report *rep) 300static int report__setup_sample_type(struct report *rep)
383{ 301{
384 struct perf_session *session = rep->session; 302 struct perf_session *session = rep->session;
385 u64 sample_type = perf_evlist__combined_sample_type(session->evlist); 303 u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
@@ -424,8 +342,7 @@ static void sig_handler(int sig __maybe_unused)
424 session_done = 1; 342 session_done = 1;
425} 343}
426 344
427static size_t hists__fprintf_nr_sample_events(struct perf_report *rep, 345static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report *rep,
428 struct hists *hists,
429 const char *evname, FILE *fp) 346 const char *evname, FILE *fp)
430{ 347{
431 size_t ret; 348 size_t ret;
@@ -462,7 +379,7 @@ static size_t hists__fprintf_nr_sample_events(struct perf_report *rep,
462} 379}
463 380
464static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, 381static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
465 struct perf_report *rep, 382 struct report *rep,
466 const char *help) 383 const char *help)
467{ 384{
468 struct perf_evsel *pos; 385 struct perf_evsel *pos;
@@ -475,7 +392,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
475 !perf_evsel__is_group_leader(pos)) 392 !perf_evsel__is_group_leader(pos))
476 continue; 393 continue;
477 394
478 hists__fprintf_nr_sample_events(rep, hists, evname, stdout); 395 hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
479 hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout); 396 hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout);
480 fprintf(stdout, "\n\n"); 397 fprintf(stdout, "\n\n");
481 } 398 }
@@ -495,7 +412,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
495 return 0; 412 return 0;
496} 413}
497 414
498static int __cmd_report(struct perf_report *rep) 415static int __cmd_report(struct report *rep)
499{ 416{
500 int ret = -EINVAL; 417 int ret = -EINVAL;
501 u64 nr_samples; 418 u64 nr_samples;
@@ -519,7 +436,7 @@ static int __cmd_report(struct perf_report *rep)
519 if (rep->show_threads) 436 if (rep->show_threads)
520 perf_read_values_init(&rep->show_threads_values); 437 perf_read_values_init(&rep->show_threads_values);
521 438
522 ret = perf_report__setup_sample_type(rep); 439 ret = report__setup_sample_type(rep);
523 if (ret) 440 if (ret)
524 return ret; 441 return ret;
525 442
@@ -552,15 +469,17 @@ static int __cmd_report(struct perf_report *rep)
552 desc); 469 desc);
553 } 470 }
554 471
555 if (verbose > 3) 472 if (use_browser == 0) {
556 perf_session__fprintf(session, stdout); 473 if (verbose > 3)
474 perf_session__fprintf(session, stdout);
557 475
558 if (verbose > 2) 476 if (verbose > 2)
559 perf_session__fprintf_dsos(session, stdout); 477 perf_session__fprintf_dsos(session, stdout);
560 478
561 if (dump_trace) { 479 if (dump_trace) {
562 perf_session__fprintf_nr_events(session, stdout); 480 perf_session__fprintf_nr_events(session, stdout);
563 return 0; 481 return 0;
482 }
564 } 483 }
565 484
566 nr_samples = 0; 485 nr_samples = 0;
@@ -638,7 +557,7 @@ static int __cmd_report(struct perf_report *rep)
638static int 557static int
639parse_callchain_opt(const struct option *opt, const char *arg, int unset) 558parse_callchain_opt(const struct option *opt, const char *arg, int unset)
640{ 559{
641 struct perf_report *rep = (struct perf_report *)opt->value; 560 struct report *rep = (struct report *)opt->value;
642 char *tok, *tok2; 561 char *tok, *tok2;
643 char *endptr; 562 char *endptr;
644 563
@@ -720,7 +639,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
720 return -1; 639 return -1;
721setup: 640setup:
722 if (callchain_register_param(&callchain_param) < 0) { 641 if (callchain_register_param(&callchain_param) < 0) {
723 fprintf(stderr, "Can't register callchain params\n"); 642 pr_err("Can't register callchain params\n");
724 return -1; 643 return -1;
725 } 644 }
726 return 0; 645 return 0;
@@ -758,7 +677,7 @@ static int
758parse_percent_limit(const struct option *opt, const char *str, 677parse_percent_limit(const struct option *opt, const char *str,
759 int unset __maybe_unused) 678 int unset __maybe_unused)
760{ 679{
761 struct perf_report *rep = opt->value; 680 struct report *rep = opt->value;
762 681
763 rep->min_percent = strtof(str, NULL); 682 rep->min_percent = strtof(str, NULL);
764 return 0; 683 return 0;
@@ -776,7 +695,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
776 "perf report [<options>]", 695 "perf report [<options>]",
777 NULL 696 NULL
778 }; 697 };
779 struct perf_report report = { 698 struct report report = {
780 .tool = { 699 .tool = {
781 .sample = process_sample_event, 700 .sample = process_sample_event,
782 .mmap = perf_event__process_mmap, 701 .mmap = perf_event__process_mmap,
@@ -892,7 +811,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
892 .mode = PERF_DATA_MODE_READ, 811 .mode = PERF_DATA_MODE_READ,
893 }; 812 };
894 813
895 perf_config(perf_report_config, &report); 814 perf_config(report__config, &report);
896 815
897 argc = parse_options(argc, argv, options, report_usage, 0); 816 argc = parse_options(argc, argv, options, report_usage, 0);
898 817
@@ -942,7 +861,7 @@ repeat:
942 } 861 }
943 if (report.mem_mode) { 862 if (report.mem_mode) {
944 if (sort__mode == SORT_MODE__BRANCH) { 863 if (sort__mode == SORT_MODE__BRANCH) {
945 fprintf(stderr, "branch and mem mode incompatible\n"); 864 pr_err("branch and mem mode incompatible\n");
946 goto error; 865 goto error;
947 } 866 }
948 sort__mode = SORT_MODE__MEMORY; 867 sort__mode = SORT_MODE__MEMORY;
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 0f3c65518a2c..6a76a07b6789 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -469,7 +469,7 @@ static void *thread_func(void *ctx)
469 char comm2[22]; 469 char comm2[22];
470 int fd; 470 int fd;
471 471
472 free(parms); 472 zfree(&parms);
473 473
474 sprintf(comm2, ":%s", this_task->comm); 474 sprintf(comm2, ":%s", this_task->comm);
475 prctl(PR_SET_NAME, comm2); 475 prctl(PR_SET_NAME, comm2);
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index f8ab125aac48..6040000bdfa6 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -423,7 +423,6 @@ static void print_sample_addr(union perf_event *event,
423static void print_sample_bts(union perf_event *event, 423static void print_sample_bts(union perf_event *event,
424 struct perf_sample *sample, 424 struct perf_sample *sample,
425 struct perf_evsel *evsel, 425 struct perf_evsel *evsel,
426 struct machine *machine,
427 struct thread *thread, 426 struct thread *thread,
428 struct addr_location *al) 427 struct addr_location *al)
429{ 428{
@@ -435,7 +434,7 @@ static void print_sample_bts(union perf_event *event,
435 printf(" "); 434 printf(" ");
436 else 435 else
437 printf("\n"); 436 printf("\n");
438 perf_evsel__print_ip(evsel, sample, machine, al, 437 perf_evsel__print_ip(evsel, sample, al,
439 output[attr->type].print_ip_opts, 438 output[attr->type].print_ip_opts,
440 PERF_MAX_STACK_DEPTH); 439 PERF_MAX_STACK_DEPTH);
441 } 440 }
@@ -446,14 +445,13 @@ static void print_sample_bts(union perf_event *event,
446 if (PRINT_FIELD(ADDR) || 445 if (PRINT_FIELD(ADDR) ||
447 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && 446 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
448 !output[attr->type].user_set)) 447 !output[attr->type].user_set))
449 print_sample_addr(event, sample, machine, thread, attr); 448 print_sample_addr(event, sample, al->machine, thread, attr);
450 449
451 printf("\n"); 450 printf("\n");
452} 451}
453 452
454static void process_event(union perf_event *event, struct perf_sample *sample, 453static void process_event(union perf_event *event, struct perf_sample *sample,
455 struct perf_evsel *evsel, struct machine *machine, 454 struct perf_evsel *evsel, struct thread *thread,
456 struct thread *thread,
457 struct addr_location *al) 455 struct addr_location *al)
458{ 456{
459 struct perf_event_attr *attr = &evsel->attr; 457 struct perf_event_attr *attr = &evsel->attr;
@@ -469,7 +467,7 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
469 } 467 }
470 468
471 if (is_bts_event(attr)) { 469 if (is_bts_event(attr)) {
472 print_sample_bts(event, sample, evsel, machine, thread, al); 470 print_sample_bts(event, sample, evsel, thread, al);
473 return; 471 return;
474 } 472 }
475 473
@@ -477,7 +475,7 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
477 event_format__print(evsel->tp_format, sample->cpu, 475 event_format__print(evsel->tp_format, sample->cpu,
478 sample->raw_data, sample->raw_size); 476 sample->raw_data, sample->raw_size);
479 if (PRINT_FIELD(ADDR)) 477 if (PRINT_FIELD(ADDR))
480 print_sample_addr(event, sample, machine, thread, attr); 478 print_sample_addr(event, sample, al->machine, thread, attr);
481 479
482 if (PRINT_FIELD(IP)) { 480 if (PRINT_FIELD(IP)) {
483 if (!symbol_conf.use_callchain) 481 if (!symbol_conf.use_callchain)
@@ -485,7 +483,7 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
485 else 483 else
486 printf("\n"); 484 printf("\n");
487 485
488 perf_evsel__print_ip(evsel, sample, machine, al, 486 perf_evsel__print_ip(evsel, sample, al,
489 output[attr->type].print_ip_opts, 487 output[attr->type].print_ip_opts,
490 PERF_MAX_STACK_DEPTH); 488 PERF_MAX_STACK_DEPTH);
491 } 489 }
@@ -574,7 +572,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
574 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) 572 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
575 return 0; 573 return 0;
576 574
577 scripting_ops->process_event(event, sample, evsel, machine, thread, &al); 575 scripting_ops->process_event(event, sample, evsel, thread, &al);
578 576
579 evsel->hists.stats.total_period += sample->period; 577 evsel->hists.stats.total_period += sample->period;
580 return 0; 578 return 0;
@@ -1104,9 +1102,9 @@ static struct script_desc *script_desc__new(const char *name)
1104 1102
1105static void script_desc__delete(struct script_desc *s) 1103static void script_desc__delete(struct script_desc *s)
1106{ 1104{
1107 free(s->name); 1105 zfree(&s->name);
1108 free(s->half_liner); 1106 zfree(&s->half_liner);
1109 free(s->args); 1107 zfree(&s->args);
1110 free(s); 1108 free(s);
1111} 1109}
1112 1110
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index dab98b50c9fe..106a5e5b7842 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -185,8 +185,7 @@ static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
185 185
186static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) 186static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
187{ 187{
188 free(evsel->priv); 188 zfree(&evsel->priv);
189 evsel->priv = NULL;
190} 189}
191 190
192static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel) 191static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
@@ -208,8 +207,7 @@ static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
208 207
209static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel) 208static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
210{ 209{
211 free(evsel->prev_raw_counts); 210 zfree(&evsel->prev_raw_counts);
212 evsel->prev_raw_counts = NULL;
213} 211}
214 212
215static void perf_evlist__free_stats(struct perf_evlist *evlist) 213static void perf_evlist__free_stats(struct perf_evlist *evlist)
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 20d4212fa337..652af0b66a62 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -488,8 +488,7 @@ static const char *cat_backtrace(union perf_event *event,
488 * It seems the callchain is corrupted. 488 * It seems the callchain is corrupted.
489 * Discard all. 489 * Discard all.
490 */ 490 */
491 free(p); 491 zfree(&p);
492 p = NULL;
493 goto exit; 492 goto exit;
494 } 493 }
495 continue; 494 continue;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 03d37a76c612..172e91a9ce62 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -189,21 +189,18 @@ static void perf_top__record_precise_ip(struct perf_top *top,
189 if (pthread_mutex_trylock(&notes->lock)) 189 if (pthread_mutex_trylock(&notes->lock))
190 return; 190 return;
191 191
192 if (notes->src == NULL && symbol__alloc_hist(sym) < 0) {
193 pthread_mutex_unlock(&notes->lock);
194 pr_err("Not enough memory for annotating '%s' symbol!\n",
195 sym->name);
196 sleep(1);
197 return;
198 }
199
200 ip = he->ms.map->map_ip(he->ms.map, ip); 192 ip = he->ms.map->map_ip(he->ms.map, ip);
201 err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip); 193 err = hist_entry__inc_addr_samples(he, counter, ip);
202 194
203 pthread_mutex_unlock(&notes->lock); 195 pthread_mutex_unlock(&notes->lock);
204 196
205 if (err == -ERANGE && !he->ms.map->erange_warned) 197 if (err == -ERANGE && !he->ms.map->erange_warned)
206 ui__warn_map_erange(he->ms.map, sym, ip); 198 ui__warn_map_erange(he->ms.map, sym, ip);
199 else if (err == -ENOMEM) {
200 pr_err("Not enough memory for annotating '%s' symbol!\n",
201 sym->name);
202 sleep(1);
203 }
207} 204}
208 205
209static void perf_top__show_details(struct perf_top *top) 206static void perf_top__show_details(struct perf_top *top)
@@ -857,7 +854,7 @@ static int perf_top__start_counters(struct perf_top *top)
857 char msg[512]; 854 char msg[512];
858 struct perf_evsel *counter; 855 struct perf_evsel *counter;
859 struct perf_evlist *evlist = top->evlist; 856 struct perf_evlist *evlist = top->evlist;
860 struct perf_record_opts *opts = &top->record_opts; 857 struct record_opts *opts = &top->record_opts;
861 858
862 perf_evlist__config(evlist, opts); 859 perf_evlist__config(evlist, opts);
863 860
@@ -909,7 +906,7 @@ static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused)
909 906
910static int __cmd_top(struct perf_top *top) 907static int __cmd_top(struct perf_top *top)
911{ 908{
912 struct perf_record_opts *opts = &top->record_opts; 909 struct record_opts *opts = &top->record_opts;
913 pthread_t thread; 910 pthread_t thread;
914 int ret; 911 int ret;
915 912
@@ -1031,7 +1028,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1031 .max_stack = PERF_MAX_STACK_DEPTH, 1028 .max_stack = PERF_MAX_STACK_DEPTH,
1032 .sym_pcnt_filter = 5, 1029 .sym_pcnt_filter = 5,
1033 }; 1030 };
1034 struct perf_record_opts *opts = &top.record_opts; 1031 struct record_opts *opts = &top.record_opts;
1035 struct target *target = &opts->target; 1032 struct target *target = &opts->target;
1036 const struct option options[] = { 1033 const struct option options[] = {
1037 OPT_CALLBACK('e', "event", &top.evlist, "event", 1034 OPT_CALLBACK('e', "event", &top.evlist, "event",
@@ -1182,7 +1179,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1182 if (top.delay_secs < 1) 1179 if (top.delay_secs < 1)
1183 top.delay_secs = 1; 1180 top.delay_secs = 1;
1184 1181
1185 if (perf_record_opts__config(opts)) { 1182 if (record_opts__config(opts)) {
1186 status = -EINVAL; 1183 status = -EINVAL;
1187 goto out_delete_maps; 1184 goto out_delete_maps;
1188 } 1185 }
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 56bbca5bc2dc..c5b4bc51175c 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -146,8 +146,7 @@ static int perf_evsel__init_tp_ptr_field(struct perf_evsel *evsel,
146 146
147static void perf_evsel__delete_priv(struct perf_evsel *evsel) 147static void perf_evsel__delete_priv(struct perf_evsel *evsel)
148{ 148{
149 free(evsel->priv); 149 zfree(&evsel->priv);
150 evsel->priv = NULL;
151 perf_evsel__delete(evsel); 150 perf_evsel__delete(evsel);
152} 151}
153 152
@@ -165,8 +164,7 @@ static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel, void *handler)
165 return -ENOMEM; 164 return -ENOMEM;
166 165
167out_delete: 166out_delete:
168 free(evsel->priv); 167 zfree(&evsel->priv);
169 evsel->priv = NULL;
170 return -ENOENT; 168 return -ENOENT;
171} 169}
172 170
@@ -1159,7 +1157,7 @@ struct trace {
1159 int max; 1157 int max;
1160 struct syscall *table; 1158 struct syscall *table;
1161 } syscalls; 1159 } syscalls;
1162 struct perf_record_opts opts; 1160 struct record_opts opts;
1163 struct machine *host; 1161 struct machine *host;
1164 u64 base_time; 1162 u64 base_time;
1165 bool full_time; 1163 bool full_time;
@@ -1278,10 +1276,8 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
1278 size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); 1276 size_t printed = syscall_arg__scnprintf_fd(bf, size, arg);
1279 struct thread_trace *ttrace = arg->thread->priv; 1277 struct thread_trace *ttrace = arg->thread->priv;
1280 1278
1281 if (ttrace && fd >= 0 && fd <= ttrace->paths.max) { 1279 if (ttrace && fd >= 0 && fd <= ttrace->paths.max)
1282 free(ttrace->paths.table[fd]); 1280 zfree(&ttrace->paths.table[fd]);
1283 ttrace->paths.table[fd] = NULL;
1284 }
1285 1281
1286 return printed; 1282 return printed;
1287} 1283}
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 5a1f4df3c3a8..14faeeb0d752 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -126,7 +126,7 @@ endif
126 126
127feature_check = $(eval $(feature_check_code)) 127feature_check = $(eval $(feature_check_code))
128define feature_check_code 128define feature_check_code
129 feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0) 129 feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
130endef 130endef
131 131
132feature_set = $(eval $(feature_set_code)) 132feature_set = $(eval $(feature_set_code))
@@ -173,7 +173,7 @@ CORE_FEATURE_TESTS = \
173# to skip the print-out of the long features list if the file 173# to skip the print-out of the long features list if the file
174# existed before and after it was built: 174# existed before and after it was built:
175# 175#
176ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all),) 176ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all.bin),)
177 test-all-failed := 1 177 test-all-failed := 1
178else 178else
179 test-all-failed := 0 179 test-all-failed := 0
@@ -203,7 +203,7 @@ ifeq ($(feature-all), 1)
203 # 203 #
204 $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat))) 204 $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat)))
205else 205else
206 $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1) 206 $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(addsuffix .bin,$(CORE_FEATURE_TESTS)) >/dev/null 2>&1)
207 $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat))) 207 $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat)))
208endif 208endif
209 209
diff --git a/tools/perf/config/feature-checks/.gitignore b/tools/perf/config/feature-checks/.gitignore
new file mode 100644
index 000000000000..80f3da0c3515
--- /dev/null
+++ b/tools/perf/config/feature-checks/.gitignore
@@ -0,0 +1,2 @@
1*.d
2*.bin
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile
index bc86462e80a2..7cf6fcdacebe 100644
--- a/tools/perf/config/feature-checks/Makefile
+++ b/tools/perf/config/feature-checks/Makefile
@@ -1,90 +1,90 @@
1 1
2FILES= \ 2FILES= \
3 test-all \ 3 test-all.bin \
4 test-backtrace \ 4 test-backtrace.bin \
5 test-bionic \ 5 test-bionic.bin \
6 test-dwarf \ 6 test-dwarf.bin \
7 test-fortify-source \ 7 test-fortify-source.bin \
8 test-glibc \ 8 test-glibc.bin \
9 test-gtk2 \ 9 test-gtk2.bin \
10 test-gtk2-infobar \ 10 test-gtk2-infobar.bin \
11 test-hello \ 11 test-hello.bin \
12 test-libaudit \ 12 test-libaudit.bin \
13 test-libbfd \ 13 test-libbfd.bin \
14 test-liberty \ 14 test-liberty.bin \
15 test-liberty-z \ 15 test-liberty-z.bin \
16 test-cplus-demangle \ 16 test-cplus-demangle.bin \
17 test-libelf \ 17 test-libelf.bin \
18 test-libelf-getphdrnum \ 18 test-libelf-getphdrnum.bin \
19 test-libelf-mmap \ 19 test-libelf-mmap.bin \
20 test-libnuma \ 20 test-libnuma.bin \
21 test-libperl \ 21 test-libperl.bin \
22 test-libpython \ 22 test-libpython.bin \
23 test-libpython-version \ 23 test-libpython-version.bin \
24 test-libslang \ 24 test-libslang.bin \
25 test-libunwind \ 25 test-libunwind.bin \
26 test-libunwind-debug-frame \ 26 test-libunwind-debug-frame.bin \
27 test-on-exit \ 27 test-on-exit.bin \
28 test-stackprotector-all \ 28 test-stackprotector-all.bin \
29 test-timerfd 29 test-timerfd.bin
30 30
31CC := $(CC) -MD 31CC := $(CC) -MD
32 32
33all: $(FILES) 33all: $(FILES)
34 34
35BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $@.c $(LDFLAGS) 35BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS)
36 36
37############################### 37###############################
38 38
39test-all: 39test-all.bin:
40 $(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl 40 $(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl
41 41
42test-hello: 42test-hello.bin:
43 $(BUILD) 43 $(BUILD)
44 44
45test-stackprotector-all: 45test-stackprotector-all.bin:
46 $(BUILD) -Werror -fstack-protector-all 46 $(BUILD) -Werror -fstack-protector-all
47 47
48test-fortify-source: 48test-fortify-source.bin:
49 $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2 49 $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2
50 50
51test-bionic: 51test-bionic.bin:
52 $(BUILD) 52 $(BUILD)
53 53
54test-libelf: 54test-libelf.bin:
55 $(BUILD) -lelf 55 $(BUILD) -lelf
56 56
57test-glibc: 57test-glibc.bin:
58 $(BUILD) 58 $(BUILD)
59 59
60test-dwarf: 60test-dwarf.bin:
61 $(BUILD) -ldw 61 $(BUILD) -ldw
62 62
63test-libelf-mmap: 63test-libelf-mmap.bin:
64 $(BUILD) -lelf 64 $(BUILD) -lelf
65 65
66test-libelf-getphdrnum: 66test-libelf-getphdrnum.bin:
67 $(BUILD) -lelf 67 $(BUILD) -lelf
68 68
69test-libnuma: 69test-libnuma.bin:
70 $(BUILD) -lnuma 70 $(BUILD) -lnuma
71 71
72test-libunwind: 72test-libunwind.bin:
73 $(BUILD) -lelf 73 $(BUILD) -lelf
74 74
75test-libunwind-debug-frame: 75test-libunwind-debug-frame.bin:
76 $(BUILD) -lelf 76 $(BUILD) -lelf
77 77
78test-libaudit: 78test-libaudit.bin:
79 $(BUILD) -laudit 79 $(BUILD) -laudit
80 80
81test-libslang: 81test-libslang.bin:
82 $(BUILD) -I/usr/include/slang -lslang 82 $(BUILD) -I/usr/include/slang -lslang
83 83
84test-gtk2: 84test-gtk2.bin:
85 $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) 85 $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
86 86
87test-gtk2-infobar: 87test-gtk2-infobar.bin:
88 $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) 88 $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
89 89
90grep-libs = $(filter -l%,$(1)) 90grep-libs = $(filter -l%,$(1))
@@ -96,7 +96,7 @@ PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
96PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` 96PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
97FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) 97FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
98 98
99test-libperl: 99test-libperl.bin:
100 $(BUILD) $(FLAGS_PERL_EMBED) 100 $(BUILD) $(FLAGS_PERL_EMBED)
101 101
102override PYTHON := python 102override PYTHON := python
@@ -113,31 +113,31 @@ PYTHON_EMBED_LIBADD = $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
113PYTHON_EMBED_CCOPTS = $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) 113PYTHON_EMBED_CCOPTS = $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
114FLAGS_PYTHON_EMBED = $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) 114FLAGS_PYTHON_EMBED = $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
115 115
116test-libpython: 116test-libpython.bin:
117 $(BUILD) $(FLAGS_PYTHON_EMBED) 117 $(BUILD) $(FLAGS_PYTHON_EMBED)
118 118
119test-libpython-version: 119test-libpython-version.bin:
120 $(BUILD) $(FLAGS_PYTHON_EMBED) 120 $(BUILD) $(FLAGS_PYTHON_EMBED)
121 121
122test-libbfd: 122test-libbfd.bin:
123 $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl 123 $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl
124 124
125test-liberty: 125test-liberty.bin:
126 $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty 126 $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty
127 127
128test-liberty-z: 128test-liberty-z.bin:
129 $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz 129 $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz
130 130
131test-cplus-demangle: 131test-cplus-demangle.bin:
132 $(BUILD) -liberty 132 $(BUILD) -liberty
133 133
134test-on-exit: 134test-on-exit.bin:
135 $(BUILD) 135 $(BUILD)
136 136
137test-backtrace: 137test-backtrace.bin:
138 $(BUILD) 138 $(BUILD)
139 139
140test-timerfd: 140test-timerfd.bin:
141 $(BUILD) 141 $(BUILD)
142 142
143-include *.d 143-include *.d
diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak
index f168debc5be2..4d985e0f03f5 100644
--- a/tools/perf/config/utilities.mak
+++ b/tools/perf/config/utilities.mak
@@ -178,10 +178,3 @@ endef
178_ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2))) 178_ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2)))
179_gea_warn = $(warning The path '$(1)' is not executable.) 179_gea_warn = $(warning The path '$(1)' is not executable.)
180_gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) 180_gea_err = $(if $(1),$(error Please set '$(1)' appropriately))
181
182ifneq ($(findstring $(MAKEFLAGS),s),s)
183 ifneq ($(V),1)
184 QUIET_CLEAN = @printf ' CLEAN %s\n' $1;
185 QUIET_INSTALL = @printf ' INSTALL %s\n' $1;
186 endif
187endif
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index b23fed527514..b1cc84b01d5b 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -247,7 +247,7 @@ enum perf_call_graph_mode {
247 CALLCHAIN_DWARF 247 CALLCHAIN_DWARF
248}; 248};
249 249
250struct perf_record_opts { 250struct record_opts {
251 struct target target; 251 struct target target;
252 int call_graph; 252 int call_graph;
253 bool group; 253 bool group;
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 85d4919dd623..4248d1e96848 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -391,7 +391,7 @@ static int do_test_code_reading(bool try_kcore)
391 struct machines machines; 391 struct machines machines;
392 struct machine *machine; 392 struct machine *machine;
393 struct thread *thread; 393 struct thread *thread;
394 struct perf_record_opts opts = { 394 struct record_opts opts = {
395 .mmap_pages = UINT_MAX, 395 .mmap_pages = UINT_MAX,
396 .user_freq = UINT_MAX, 396 .user_freq = UINT_MAX,
397 .user_interval = ULLONG_MAX, 397 .user_interval = ULLONG_MAX,
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index 376c35608534..27eb75142b88 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -51,7 +51,7 @@ static int find_comm(struct perf_evlist *evlist, const char *comm)
51 */ 51 */
52int test__keep_tracking(void) 52int test__keep_tracking(void)
53{ 53{
54 struct perf_record_opts opts = { 54 struct record_opts opts = {
55 .mmap_pages = UINT_MAX, 55 .mmap_pages = UINT_MAX,
56 .user_freq = UINT_MAX, 56 .user_freq = UINT_MAX,
57 .user_interval = ULLONG_MAX, 57 .user_interval = ULLONG_MAX,
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 2ca0abf1b2b6..f641c35f2321 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -106,10 +106,36 @@ test_make_python_perf_so := test -f $(PERF)/python/perf.so
106test_make_perf_o := test -f $(PERF)/perf.o 106test_make_perf_o := test -f $(PERF)/perf.o
107test_make_util_map_o := test -f $(PERF)/util/map.o 107test_make_util_map_o := test -f $(PERF)/util/map.o
108 108
109test_make_install := test -x $$TMP_DEST/bin/perf 109define test_dest_files
110test_make_install_O := $(test_make_install) 110 for file in $(1); do \
111test_make_install_bin := $(test_make_install) 111 if [ ! -x $$TMP_DEST/$$file ]; then \
112test_make_install_bin_O := $(test_make_install) 112 echo " failed to find: $$file"; \
113 fi \
114 done
115endef
116
117installed_files_bin := bin/perf
118installed_files_bin += etc/bash_completion.d/perf
119installed_files_bin += libexec/perf-core/perf-archive
120
121installed_files_plugins := lib64/traceevent/plugins/plugin_cfg80211.so
122installed_files_plugins += lib64/traceevent/plugins/plugin_scsi.so
123installed_files_plugins += lib64/traceevent/plugins/plugin_xen.so
124installed_files_plugins += lib64/traceevent/plugins/plugin_function.so
125installed_files_plugins += lib64/traceevent/plugins/plugin_sched_switch.so
126installed_files_plugins += lib64/traceevent/plugins/plugin_mac80211.so
127installed_files_plugins += lib64/traceevent/plugins/plugin_kvm.so
128installed_files_plugins += lib64/traceevent/plugins/plugin_kmem.so
129installed_files_plugins += lib64/traceevent/plugins/plugin_hrtimer.so
130installed_files_plugins += lib64/traceevent/plugins/plugin_jbd2.so
131
132installed_files_all := $(installed_files_bin)
133installed_files_all += $(installed_files_plugins)
134
135test_make_install := $(call test_dest_files,$(installed_files_all))
136test_make_install_O := $(call test_dest_files,$(installed_files_all))
137test_make_install_bin := $(call test_dest_files,$(installed_files_bin))
138test_make_install_bin_O := $(call test_dest_files,$(installed_files_bin))
113 139
114# FIXME nothing gets installed 140# FIXME nothing gets installed
115test_make_install_man := test -f $$TMP_DEST/share/man/man1/perf.1 141test_make_install_man := test -f $$TMP_DEST/share/man/man1/perf.1
@@ -162,7 +188,7 @@ $(run):
162 cmd="cd $(PERF) && make -f $(MK) DESTDIR=$$TMP_DEST $($@)"; \ 188 cmd="cd $(PERF) && make -f $(MK) DESTDIR=$$TMP_DEST $($@)"; \
163 echo "- $@: $$cmd" && echo $$cmd > $@ && \ 189 echo "- $@: $$cmd" && echo $$cmd > $@ && \
164 ( eval $$cmd ) >> $@ 2>&1; \ 190 ( eval $$cmd ) >> $@ 2>&1; \
165 echo " test: $(call test,$@)"; \ 191 echo " test: $(call test,$@)" >> $@ 2>&1; \
166 $(call test,$@) && \ 192 $(call test,$@) && \
167 rm -f $@ \ 193 rm -f $@ \
168 rm -rf $$TMP_DEST 194 rm -rf $$TMP_DEST
@@ -174,7 +200,7 @@ $(run_O):
174 cmd="cd $(PERF) && make -f $(MK) O=$$TMP_O DESTDIR=$$TMP_DEST $($(patsubst %_O,%,$@))"; \ 200 cmd="cd $(PERF) && make -f $(MK) O=$$TMP_O DESTDIR=$$TMP_DEST $($(patsubst %_O,%,$@))"; \
175 echo "- $@: $$cmd" && echo $$cmd > $@ && \ 201 echo "- $@: $$cmd" && echo $$cmd > $@ && \
176 ( eval $$cmd ) >> $@ 2>&1 && \ 202 ( eval $$cmd ) >> $@ 2>&1 && \
177 echo " test: $(call test_O,$@)"; \ 203 echo " test: $(call test_O,$@)" >> $@ 2>&1; \
178 $(call test_O,$@) && \ 204 $(call test_O,$@) && \
179 rm -f $@ && \ 205 rm -f $@ && \
180 rm -rf $$TMP_O \ 206 rm -rf $$TMP_O \
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index 41cc0badb74b..774620a5aecb 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -6,7 +6,7 @@
6 6
7int test__syscall_open_tp_fields(void) 7int test__syscall_open_tp_fields(void)
8{ 8{
9 struct perf_record_opts opts = { 9 struct record_opts opts = {
10 .target = { 10 .target = {
11 .uid = UINT_MAX, 11 .uid = UINT_MAX,
12 .uses_mmap = true, 12 .uses_mmap = true,
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index 93a62b06c3af..eeba562920e9 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -34,7 +34,7 @@ realloc:
34 34
35int test__PERF_RECORD(void) 35int test__PERF_RECORD(void)
36{ 36{
37 struct perf_record_opts opts = { 37 struct record_opts opts = {
38 .target = { 38 .target = {
39 .uid = UINT_MAX, 39 .uid = UINT_MAX,
40 .uses_mmap = true, 40 .uses_mmap = true,
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 4ca1b938f6a6..c6398b90e897 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -46,7 +46,7 @@ static u64 rdtsc(void)
46 */ 46 */
47int test__perf_time_to_tsc(void) 47int test__perf_time_to_tsc(void)
48{ 48{
49 struct perf_record_opts opts = { 49 struct record_opts opts = {
50 .mmap_pages = UINT_MAX, 50 .mmap_pages = UINT_MAX,
51 .user_freq = UINT_MAX, 51 .user_freq = UINT_MAX,
52 .user_interval = ULLONG_MAX, 52 .user_interval = ULLONG_MAX,
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index cbaa7af45513..d11541d4d7d7 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -256,8 +256,7 @@ int ui_browser__show(struct ui_browser *browser, const char *title,
256 __ui_browser__show_title(browser, title); 256 __ui_browser__show_title(browser, title);
257 257
258 browser->title = title; 258 browser->title = title;
259 free(browser->helpline); 259 zfree(&browser->helpline);
260 browser->helpline = NULL;
261 260
262 va_start(ap, helpline); 261 va_start(ap, helpline);
263 err = vasprintf(&browser->helpline, helpline, ap); 262 err = vasprintf(&browser->helpline, helpline, ap);
@@ -268,12 +267,11 @@ int ui_browser__show(struct ui_browser *browser, const char *title,
268 return err ? 0 : -1; 267 return err ? 0 : -1;
269} 268}
270 269
271void ui_browser__hide(struct ui_browser *browser __maybe_unused) 270void ui_browser__hide(struct ui_browser *browser)
272{ 271{
273 pthread_mutex_lock(&ui__lock); 272 pthread_mutex_lock(&ui__lock);
274 ui_helpline__pop(); 273 ui_helpline__pop();
275 free(browser->helpline); 274 zfree(&browser->helpline);
276 browser->helpline = NULL;
277 pthread_mutex_unlock(&ui__lock); 275 pthread_mutex_unlock(&ui__lock);
278} 276}
279 277
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index 7d45d2f53601..118cca29dd26 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -59,6 +59,8 @@ int ui_browser__help_window(struct ui_browser *browser, const char *text);
59bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text); 59bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text);
60int ui_browser__input_window(const char *title, const char *text, char *input, 60int ui_browser__input_window(const char *title, const char *text, char *input,
61 const char *exit_msg, int delay_sec); 61 const char *exit_msg, int delay_sec);
62struct perf_session_env;
63int tui__header_window(struct perf_session_env *env);
62 64
63void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence); 65void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence);
64unsigned int ui_browser__argv_refresh(struct ui_browser *browser); 66unsigned int ui_browser__argv_refresh(struct ui_browser *browser);
diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c
new file mode 100644
index 000000000000..89c16b988618
--- /dev/null
+++ b/tools/perf/ui/browsers/header.c
@@ -0,0 +1,127 @@
1#include "util/cache.h"
2#include "util/debug.h"
3#include "ui/browser.h"
4#include "ui/ui.h"
5#include "ui/util.h"
6#include "ui/libslang.h"
7#include "util/header.h"
8#include "util/session.h"
9
10static void ui_browser__argv_write(struct ui_browser *browser,
11 void *entry, int row)
12{
13 char **arg = entry;
14 char *str = *arg;
15 char empty[] = " ";
16 bool current_entry = ui_browser__is_current_entry(browser, row);
17 unsigned long offset = (unsigned long)browser->priv;
18
19 if (offset >= strlen(str))
20 str = empty;
21 else
22 str = str + offset;
23
24 ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
25 HE_COLORSET_NORMAL);
26
27 slsmg_write_nstring(str, browser->width);
28}
29
30static int list_menu__run(struct ui_browser *menu)
31{
32 int key;
33 unsigned long offset;
34 const char help[] =
35 "h/?/F1 Show this window\n"
36 "UP/DOWN/PGUP\n"
37 "PGDN/SPACE\n"
38 "LEFT/RIGHT Navigate\n"
39 "q/ESC/CTRL+C Exit browser";
40
41 if (ui_browser__show(menu, "Header information", "Press 'q' to exit") < 0)
42 return -1;
43
44 while (1) {
45 key = ui_browser__run(menu, 0);
46
47 switch (key) {
48 case K_RIGHT:
49 offset = (unsigned long)menu->priv;
50 offset += 10;
51 menu->priv = (void *)offset;
52 continue;
53 case K_LEFT:
54 offset = (unsigned long)menu->priv;
55 if (offset >= 10)
56 offset -= 10;
57 menu->priv = (void *)offset;
58 continue;
59 case K_F1:
60 case 'h':
61 case '?':
62 ui_browser__help_window(menu, help);
63 continue;
64 case K_ESC:
65 case 'q':
66 case CTRL('c'):
67 key = -1;
68 break;
69 default:
70 continue;
71 }
72
73 break;
74 }
75
76 ui_browser__hide(menu);
77 return key;
78}
79
80static int ui__list_menu(int argc, char * const argv[])
81{
82 struct ui_browser menu = {
83 .entries = (void *)argv,
84 .refresh = ui_browser__argv_refresh,
85 .seek = ui_browser__argv_seek,
86 .write = ui_browser__argv_write,
87 .nr_entries = argc,
88 };
89
90 return list_menu__run(&menu);
91}
92
93int tui__header_window(struct perf_session_env *env)
94{
95 int i, argc = 0;
96 char **argv;
97 struct perf_session *session;
98 char *ptr, *pos;
99 size_t size;
100 FILE *fp = open_memstream(&ptr, &size);
101
102 session = container_of(env, struct perf_session, header.env);
103 perf_header__fprintf_info(session, fp, true);
104 fclose(fp);
105
106 for (pos = ptr, argc = 0; (pos = strchr(pos, '\n')) != NULL; pos++)
107 argc++;
108
109 argv = calloc(argc + 1, sizeof(*argv));
110 if (argv == NULL)
111 goto out;
112
113 argv[0] = pos = ptr;
114 for (i = 1; (pos = strchr(pos, '\n')) != NULL; i++) {
115 *pos++ = '\0';
116 argv[i] = pos;
117 }
118
119 BUG_ON(i != argc + 1);
120
121 ui__list_menu(argc, argv);
122
123out:
124 free(argv);
125 free(ptr);
126 return 0;
127}
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a440e03cd8c2..a7045ea6d1d5 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1267,10 +1267,8 @@ static inline void free_popup_options(char **options, int n)
1267{ 1267{
1268 int i; 1268 int i;
1269 1269
1270 for (i = 0; i < n; ++i) { 1270 for (i = 0; i < n; ++i)
1271 free(options[i]); 1271 zfree(&options[i]);
1272 options[i] = NULL;
1273 }
1274} 1272}
1275 1273
1276/* Check whether the browser is for 'top' or 'report' */ 1274/* Check whether the browser is for 'top' or 'report' */
@@ -1329,7 +1327,7 @@ static int switch_data_file(void)
1329 1327
1330 abs_path[nr_options] = strdup(path); 1328 abs_path[nr_options] = strdup(path);
1331 if (!abs_path[nr_options]) { 1329 if (!abs_path[nr_options]) {
1332 free(options[nr_options]); 1330 zfree(&options[nr_options]);
1333 ui__warning("Can't search all data files due to memory shortage.\n"); 1331 ui__warning("Can't search all data files due to memory shortage.\n");
1334 fclose(file); 1332 fclose(file);
1335 break; 1333 break;
@@ -1400,6 +1398,36 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1400 char script_opt[64]; 1398 char script_opt[64];
1401 int delay_secs = hbt ? hbt->refresh : 0; 1399 int delay_secs = hbt ? hbt->refresh : 0;
1402 1400
1401#define HIST_BROWSER_HELP_COMMON \
1402 "h/?/F1 Show this window\n" \
1403 "UP/DOWN/PGUP\n" \
1404 "PGDN/SPACE Navigate\n" \
1405 "q/ESC/CTRL+C Exit browser\n\n" \
1406 "For multiple event sessions:\n\n" \
1407 "TAB/UNTAB Switch events\n\n" \
1408 "For symbolic views (--sort has sym):\n\n" \
1409 "-> Zoom into DSO/Threads & Annotate current symbol\n" \
1410 "<- Zoom out\n" \
1411 "a Annotate current symbol\n" \
1412 "C Collapse all callchains\n" \
1413 "d Zoom into current DSO\n" \
1414 "E Expand all callchains\n" \
1415
1416 /* help messages are sorted by lexical order of the hotkey */
1417 const char report_help[] = HIST_BROWSER_HELP_COMMON
1418 "i Show header information\n"
1419 "P Print histograms to perf.hist.N\n"
1420 "r Run available scripts\n"
1421 "s Switch to another data file in PWD\n"
1422 "t Zoom into current Thread\n"
1423 "V Verbose (DSO names in callchains, etc)\n"
1424 "/ Filter symbol by name";
1425 const char top_help[] = HIST_BROWSER_HELP_COMMON
1426 "P Print histograms to perf.hist.N\n"
1427 "t Zoom into current Thread\n"
1428 "V Verbose (DSO names in callchains, etc)\n"
1429 "/ Filter symbol by name";
1430
1403 if (browser == NULL) 1431 if (browser == NULL)
1404 return -1; 1432 return -1;
1405 1433
@@ -1484,29 +1512,16 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1484 if (is_report_browser(hbt)) 1512 if (is_report_browser(hbt))
1485 goto do_data_switch; 1513 goto do_data_switch;
1486 continue; 1514 continue;
1515 case 'i':
1516 /* env->arch is NULL for live-mode (i.e. perf top) */
1517 if (env->arch)
1518 tui__header_window(env);
1519 continue;
1487 case K_F1: 1520 case K_F1:
1488 case 'h': 1521 case 'h':
1489 case '?': 1522 case '?':
1490 ui_browser__help_window(&browser->b, 1523 ui_browser__help_window(&browser->b,
1491 "h/?/F1 Show this window\n" 1524 is_report_browser(hbt) ? report_help : top_help);
1492 "UP/DOWN/PGUP\n"
1493 "PGDN/SPACE Navigate\n"
1494 "q/ESC/CTRL+C Exit browser\n\n"
1495 "For multiple event sessions:\n\n"
1496 "TAB/UNTAB Switch events\n\n"
1497 "For symbolic views (--sort has sym):\n\n"
1498 "-> Zoom into DSO/Threads & Annotate current symbol\n"
1499 "<- Zoom out\n"
1500 "a Annotate current symbol\n"
1501 "C Collapse all callchains\n"
1502 "E Expand all callchains\n"
1503 "d Zoom into current DSO\n"
1504 "t Zoom into current Thread\n"
1505 "r Run available scripts('perf report' only)\n"
1506 "s Switch to another data file in PWD ('perf report' only)\n"
1507 "P Print histograms to perf.hist.N\n"
1508 "V Verbose (DSO names in callchains, etc)\n"
1509 "/ Filter symbol by name");
1510 continue; 1525 continue;
1511 case K_ENTER: 1526 case K_ENTER:
1512 case K_RIGHT: 1527 case K_RIGHT:
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c
index d63c68ea02a8..402d2bd30b09 100644
--- a/tools/perf/ui/browsers/scripts.c
+++ b/tools/perf/ui/browsers/scripts.c
@@ -173,8 +173,7 @@ int script_browse(const char *script_opt)
173 if (script.b.width > AVERAGE_LINE_LEN) 173 if (script.b.width > AVERAGE_LINE_LEN)
174 script.b.width = AVERAGE_LINE_LEN; 174 script.b.width = AVERAGE_LINE_LEN;
175 175
176 if (line) 176 free(line);
177 free(line);
178 pclose(fp); 177 pclose(fp);
179 178
180 script.nr_lines = nr_entries; 179 script.nr_lines = nr_entries;
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c
index 696c1fbe4248..52e7fc48af9f 100644
--- a/tools/perf/ui/gtk/util.c
+++ b/tools/perf/ui/gtk/util.c
@@ -23,8 +23,7 @@ int perf_gtk__deactivate_context(struct perf_gtk_context **ctx)
23 if (!perf_gtk__is_active_context(*ctx)) 23 if (!perf_gtk__is_active_context(*ctx))
24 return -1; 24 return -1;
25 25
26 free(*ctx); 26 zfree(ctx);
27 *ctx = NULL;
28 return 0; 27 return 0;
29} 28}
30 29
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index c244cb524ef2..831fbb77d1ff 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -510,7 +510,7 @@ print_entries:
510 510
511 free(line); 511 free(line);
512out: 512out:
513 free(rem_sq_bracket); 513 zfree(&rem_sq_bracket);
514 514
515 return ret; 515 return ret;
516} 516}
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c
index 092902e30cee..bf890f72fe80 100644
--- a/tools/perf/ui/tui/util.c
+++ b/tools/perf/ui/tui/util.c
@@ -92,6 +92,8 @@ int ui_browser__input_window(const char *title, const char *text, char *input,
92 t = sep + 1; 92 t = sep + 1;
93 } 93 }
94 94
95 pthread_mutex_lock(&ui__lock);
96
95 max_len += 2; 97 max_len += 2;
96 nr_lines += 8; 98 nr_lines += 8;
97 y = SLtt_Screen_Rows / 2 - nr_lines / 2; 99 y = SLtt_Screen_Rows / 2 - nr_lines / 2;
@@ -120,13 +122,19 @@ int ui_browser__input_window(const char *title, const char *text, char *input,
120 SLsmg_write_nstring((char *)exit_msg, max_len); 122 SLsmg_write_nstring((char *)exit_msg, max_len);
121 SLsmg_refresh(); 123 SLsmg_refresh();
122 124
125 pthread_mutex_unlock(&ui__lock);
126
123 x += 2; 127 x += 2;
124 len = 0; 128 len = 0;
125 key = ui__getch(delay_secs); 129 key = ui__getch(delay_secs);
126 while (key != K_TIMER && key != K_ENTER && key != K_ESC) { 130 while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
131 pthread_mutex_lock(&ui__lock);
132
127 if (key == K_BKSPC) { 133 if (key == K_BKSPC) {
128 if (len == 0) 134 if (len == 0) {
135 pthread_mutex_unlock(&ui__lock);
129 goto next_key; 136 goto next_key;
137 }
130 SLsmg_gotorc(y, x + --len); 138 SLsmg_gotorc(y, x + --len);
131 SLsmg_write_char(' '); 139 SLsmg_write_char(' ');
132 } else { 140 } else {
@@ -136,6 +144,8 @@ int ui_browser__input_window(const char *title, const char *text, char *input,
136 } 144 }
137 SLsmg_refresh(); 145 SLsmg_refresh();
138 146
147 pthread_mutex_unlock(&ui__lock);
148
139 /* XXX more graceful overflow handling needed */ 149 /* XXX more graceful overflow handling needed */
140 if (len == sizeof(buf) - 1) { 150 if (len == sizeof(buf) - 1) {
141 ui_helpline__push("maximum size of symbol name reached!"); 151 ui_helpline__push("maximum size of symbol name reached!");
@@ -174,6 +184,8 @@ int ui__question_window(const char *title, const char *text,
174 t = sep + 1; 184 t = sep + 1;
175 } 185 }
176 186
187 pthread_mutex_lock(&ui__lock);
188
177 max_len += 2; 189 max_len += 2;
178 nr_lines += 4; 190 nr_lines += 4;
179 y = SLtt_Screen_Rows / 2 - nr_lines / 2, 191 y = SLtt_Screen_Rows / 2 - nr_lines / 2,
@@ -195,6 +207,9 @@ int ui__question_window(const char *title, const char *text,
195 SLsmg_gotorc(y + nr_lines - 1, x); 207 SLsmg_gotorc(y + nr_lines - 1, x);
196 SLsmg_write_nstring((char *)exit_msg, max_len); 208 SLsmg_write_nstring((char *)exit_msg, max_len);
197 SLsmg_refresh(); 209 SLsmg_refresh();
210
211 pthread_mutex_unlock(&ui__lock);
212
198 return ui__getch(delay_secs); 213 return ui__getch(delay_secs);
199} 214}
200 215
@@ -215,9 +230,7 @@ static int __ui__warning(const char *title, const char *format, va_list args)
215 if (vasprintf(&s, format, args) > 0) { 230 if (vasprintf(&s, format, args) > 0) {
216 int key; 231 int key;
217 232
218 pthread_mutex_lock(&ui__lock);
219 key = ui__question_window(title, s, "Press any key...", 0); 233 key = ui__question_window(title, s, "Press any key...", 0);
220 pthread_mutex_unlock(&ui__lock);
221 free(s); 234 free(s);
222 return key; 235 return key;
223 } 236 }
diff --git a/tools/perf/util/alias.c b/tools/perf/util/alias.c
index e6d134773d0a..c0b43ee40d95 100644
--- a/tools/perf/util/alias.c
+++ b/tools/perf/util/alias.c
@@ -55,8 +55,7 @@ int split_cmdline(char *cmdline, const char ***argv)
55 src++; 55 src++;
56 c = cmdline[src]; 56 c = cmdline[src];
57 if (!c) { 57 if (!c) {
58 free(*argv); 58 zfree(argv);
59 *argv = NULL;
60 return error("cmdline ends with \\"); 59 return error("cmdline ends with \\");
61 } 60 }
62 } 61 }
@@ -68,8 +67,7 @@ int split_cmdline(char *cmdline, const char ***argv)
68 cmdline[dst] = 0; 67 cmdline[dst] = 0;
69 68
70 if (quoted) { 69 if (quoted) {
71 free(*argv); 70 zfree(argv);
72 *argv = NULL;
73 return error("unclosed quote"); 71 return error("unclosed quote");
74 } 72 }
75 73
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 0fcd81ea31ae..469eb679fb9d 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -26,10 +26,10 @@ static int disasm_line__parse(char *line, char **namep, char **rawp);
26 26
27static void ins__delete(struct ins_operands *ops) 27static void ins__delete(struct ins_operands *ops)
28{ 28{
29 free(ops->source.raw); 29 zfree(&ops->source.raw);
30 free(ops->source.name); 30 zfree(&ops->source.name);
31 free(ops->target.raw); 31 zfree(&ops->target.raw);
32 free(ops->target.name); 32 zfree(&ops->target.name);
33} 33}
34 34
35static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, 35static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size,
@@ -185,8 +185,7 @@ static int lock__parse(struct ins_operands *ops)
185 return 0; 185 return 0;
186 186
187out_free_ops: 187out_free_ops:
188 free(ops->locked.ops); 188 zfree(&ops->locked.ops);
189 ops->locked.ops = NULL;
190 return 0; 189 return 0;
191} 190}
192 191
@@ -205,9 +204,9 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size,
205 204
206static void lock__delete(struct ins_operands *ops) 205static void lock__delete(struct ins_operands *ops)
207{ 206{
208 free(ops->locked.ops); 207 zfree(&ops->locked.ops);
209 free(ops->target.raw); 208 zfree(&ops->target.raw);
210 free(ops->target.name); 209 zfree(&ops->target.name);
211} 210}
212 211
213static struct ins_ops lock_ops = { 212static struct ins_ops lock_ops = {
@@ -256,8 +255,7 @@ static int mov__parse(struct ins_operands *ops)
256 return 0; 255 return 0;
257 256
258out_free_source: 257out_free_source:
259 free(ops->source.raw); 258 zfree(&ops->source.raw);
260 ops->source.raw = NULL;
261 return -1; 259 return -1;
262} 260}
263 261
@@ -464,17 +462,12 @@ void symbol__annotate_zero_histograms(struct symbol *sym)
464 pthread_mutex_unlock(&notes->lock); 462 pthread_mutex_unlock(&notes->lock);
465} 463}
466 464
467int symbol__inc_addr_samples(struct symbol *sym, struct map *map, 465static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
468 int evidx, u64 addr) 466 struct annotation *notes, int evidx, u64 addr)
469{ 467{
470 unsigned offset; 468 unsigned offset;
471 struct annotation *notes;
472 struct sym_hist *h; 469 struct sym_hist *h;
473 470
474 notes = symbol__annotation(sym);
475 if (notes->src == NULL)
476 return -ENOMEM;
477
478 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); 471 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
479 472
480 if (addr < sym->start || addr > sym->end) 473 if (addr < sym->start || addr > sym->end)
@@ -491,6 +484,33 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
491 return 0; 484 return 0;
492} 485}
493 486
487static int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
488 int evidx, u64 addr)
489{
490 struct annotation *notes;
491
492 if (sym == NULL || use_browser != 1 || !sort__has_sym)
493 return 0;
494
495 notes = symbol__annotation(sym);
496 if (notes->src == NULL) {
497 if (symbol__alloc_hist(sym) < 0)
498 return -ENOMEM;
499 }
500
501 return __symbol__inc_addr_samples(sym, map, notes, evidx, addr);
502}
503
504int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx)
505{
506 return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr);
507}
508
509int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip)
510{
511 return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip);
512}
513
494static void disasm_line__init_ins(struct disasm_line *dl) 514static void disasm_line__init_ins(struct disasm_line *dl)
495{ 515{
496 dl->ins = ins__find(dl->name); 516 dl->ins = ins__find(dl->name);
@@ -538,8 +558,7 @@ static int disasm_line__parse(char *line, char **namep, char **rawp)
538 return 0; 558 return 0;
539 559
540out_free_name: 560out_free_name:
541 free(*namep); 561 zfree(namep);
542 *namep = NULL;
543 return -1; 562 return -1;
544} 563}
545 564
@@ -564,7 +583,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privs
564 return dl; 583 return dl;
565 584
566out_free_line: 585out_free_line:
567 free(dl->line); 586 zfree(&dl->line);
568out_delete: 587out_delete:
569 free(dl); 588 free(dl);
570 return NULL; 589 return NULL;
@@ -572,8 +591,8 @@ out_delete:
572 591
573void disasm_line__free(struct disasm_line *dl) 592void disasm_line__free(struct disasm_line *dl)
574{ 593{
575 free(dl->line); 594 zfree(&dl->line);
576 free(dl->name); 595 zfree(&dl->name);
577 if (dl->ins && dl->ins->ops->free) 596 if (dl->ins && dl->ins->ops->free)
578 dl->ins->ops->free(&dl->ops); 597 dl->ins->ops->free(&dl->ops);
579 else 598 else
@@ -1091,8 +1110,7 @@ static void symbol__free_source_line(struct symbol *sym, int len)
1091 src_line = (void *)src_line + sizeof_src_line; 1110 src_line = (void *)src_line + sizeof_src_line;
1092 } 1111 }
1093 1112
1094 free(notes->src->lines); 1113 zfree(&notes->src->lines);
1095 notes->src->lines = NULL;
1096} 1114}
1097 1115
1098/* Get the filename:line for the colored entries */ 1116/* Get the filename:line for the colored entries */
@@ -1376,3 +1394,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
1376 1394
1377 return 0; 1395 return 0;
1378} 1396}
1397
1398int hist_entry__annotate(struct hist_entry *he, size_t privsize)
1399{
1400 return symbol__annotate(he->ms.sym, he->ms.map, privsize);
1401}
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 834b7b57b788..b2aef59d6bb2 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -132,12 +132,17 @@ static inline struct annotation *symbol__annotation(struct symbol *sym)
132 return &a->annotation; 132 return &a->annotation;
133} 133}
134 134
135int symbol__inc_addr_samples(struct symbol *sym, struct map *map, 135int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx);
136 int evidx, u64 addr); 136
137int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
138
137int symbol__alloc_hist(struct symbol *sym); 139int symbol__alloc_hist(struct symbol *sym);
138void symbol__annotate_zero_histograms(struct symbol *sym); 140void symbol__annotate_zero_histograms(struct symbol *sym);
139 141
140int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); 142int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize);
143
144int hist_entry__annotate(struct hist_entry *he, size_t privsize);
145
141int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym); 146int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym);
142int symbol__annotate_printf(struct symbol *sym, struct map *map, 147int symbol__annotate_printf(struct symbol *sym, struct map *map,
143 struct perf_evsel *evsel, bool full_paths, 148 struct perf_evsel *evsel, bool full_paths,
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 4f7f989876ec..08b25af9eea1 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -146,7 +146,7 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
146 146
147struct option; 147struct option;
148 148
149int record_parse_callchain(const char *arg, struct perf_record_opts *opts); 149int record_parse_callchain(const char *arg, struct record_opts *opts);
150int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); 150int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
151int record_callchain_opt(const struct option *opt, const char *arg, int unset); 151int record_callchain_opt(const struct option *opt, const char *arg, int unset);
152 152
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
index 96bbda1ddb83..0922aa4218c2 100644
--- a/tools/perf/util/cgroup.c
+++ b/tools/perf/util/cgroup.c
@@ -133,7 +133,7 @@ void close_cgroup(struct cgroup_sel *cgrp)
133 /* XXX: not reentrant */ 133 /* XXX: not reentrant */
134 if (--cgrp->refcnt == 0) { 134 if (--cgrp->refcnt == 0) {
135 close(cgrp->fd); 135 close(cgrp->fd);
136 free(cgrp->name); 136 zfree(&cgrp->name);
137 free(cgrp); 137 free(cgrp);
138 } 138 }
139} 139}
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
index ee0df0e24cdb..67d1e404c0cb 100644
--- a/tools/perf/util/comm.c
+++ b/tools/perf/util/comm.c
@@ -21,7 +21,7 @@ static void comm_str__put(struct comm_str *cs)
21{ 21{
22 if (!--cs->ref) { 22 if (!--cs->ref) {
23 rb_erase(&cs->rb_node, &comm_str_root); 23 rb_erase(&cs->rb_node, &comm_str_root);
24 free(cs->str); 24 zfree(&cs->str);
25 free(cs); 25 free(cs);
26 } 26 }
27} 27}
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index 8640a9121e72..299b55586502 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -25,7 +25,6 @@ static int _eprintf(int level, const char *fmt, va_list args)
25 ui_helpline__vshow(fmt, args); 25 ui_helpline__vshow(fmt, args);
26 else 26 else
27 ret = vfprintf(stderr, fmt, args); 27 ret = vfprintf(stderr, fmt, args);
28 va_end(args);
29 } 28 }
30 29
31 return ret; 30 return ret;
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 4ddeecb9ff85..4045d086d9d9 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -497,21 +497,18 @@ void dso__delete(struct dso *dso)
497 symbols__delete(&dso->symbols[i]); 497 symbols__delete(&dso->symbols[i]);
498 498
499 if (dso->short_name_allocated) { 499 if (dso->short_name_allocated) {
500 free((char *)dso->short_name); 500 zfree((char **)&dso->short_name);
501 dso->short_name = NULL;
502 dso->short_name_allocated = false; 501 dso->short_name_allocated = false;
503 } 502 }
504 503
505 if (dso->long_name_allocated) { 504 if (dso->long_name_allocated) {
506 free((char *)dso->long_name); 505 zfree((char **)&dso->long_name);
507 dso->long_name = NULL;
508 dso->long_name_allocated = false; 506 dso->long_name_allocated = false;
509 } 507 }
510 508
511 dso_cache__free(&dso->cache); 509 dso_cache__free(&dso->cache);
512 dso__free_a2l(dso); 510 dso__free_a2l(dso);
513 free(dso->symsrc_filename); 511 zfree(&dso->symsrc_filename);
514 dso->symsrc_filename = NULL;
515 free(dso); 512 free(dso);
516} 513}
517 514
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 694876877ae2..45a76c69a9ed 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -106,8 +106,12 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
106 106
107 memset(&event->comm, 0, sizeof(event->comm)); 107 memset(&event->comm, 0, sizeof(event->comm));
108 108
109 tgid = perf_event__get_comm_tgid(pid, event->comm.comm, 109 if (machine__is_host(machine))
110 sizeof(event->comm.comm)); 110 tgid = perf_event__get_comm_tgid(pid, event->comm.comm,
111 sizeof(event->comm.comm));
112 else
113 tgid = machine->pid;
114
111 if (tgid < 0) 115 if (tgid < 0)
112 goto out; 116 goto out;
113 117
@@ -129,7 +133,11 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
129 goto out; 133 goto out;
130 } 134 }
131 135
132 snprintf(filename, sizeof(filename), "/proc/%d/task", pid); 136 if (machine__is_default_guest(machine))
137 return 0;
138
139 snprintf(filename, sizeof(filename), "%s/proc/%d/task",
140 machine->root_dir, pid);
133 141
134 tasks = opendir(filename); 142 tasks = opendir(filename);
135 if (tasks == NULL) { 143 if (tasks == NULL) {
@@ -178,7 +186,11 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
178 FILE *fp; 186 FILE *fp;
179 int rc = 0; 187 int rc = 0;
180 188
181 snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); 189 if (machine__is_default_guest(machine))
190 return 0;
191
192 snprintf(filename, sizeof(filename), "%s/proc/%d/maps",
193 machine->root_dir, pid);
182 194
183 fp = fopen(filename, "r"); 195 fp = fopen(filename, "r");
184 if (fp == NULL) { 196 if (fp == NULL) {
@@ -218,7 +230,10 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
218 /* 230 /*
219 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c 231 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
220 */ 232 */
221 event->header.misc = PERF_RECORD_MISC_USER; 233 if (machine__is_host(machine))
234 event->header.misc = PERF_RECORD_MISC_USER;
235 else
236 event->header.misc = PERF_RECORD_MISC_GUEST_USER;
222 237
223 if (prot[2] != 'x') { 238 if (prot[2] != 'x') {
224 if (!mmap_data || prot[0] != 'r') 239 if (!mmap_data || prot[0] != 'r')
@@ -387,6 +402,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
387 struct machine *machine, bool mmap_data) 402 struct machine *machine, bool mmap_data)
388{ 403{
389 DIR *proc; 404 DIR *proc;
405 char proc_path[PATH_MAX];
390 struct dirent dirent, *next; 406 struct dirent dirent, *next;
391 union perf_event *comm_event, *mmap_event; 407 union perf_event *comm_event, *mmap_event;
392 int err = -1; 408 int err = -1;
@@ -399,7 +415,12 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
399 if (mmap_event == NULL) 415 if (mmap_event == NULL)
400 goto out_free_comm; 416 goto out_free_comm;
401 417
402 proc = opendir("/proc"); 418 if (machine__is_default_guest(machine))
419 return 0;
420
421 snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
422 proc = opendir(proc_path);
423
403 if (proc == NULL) 424 if (proc == NULL)
404 goto out_free_mmap; 425 goto out_free_mmap;
405 426
@@ -638,6 +659,7 @@ void thread__find_addr_map(struct thread *thread,
638 struct map_groups *mg = &thread->mg; 659 struct map_groups *mg = &thread->mg;
639 bool load_map = false; 660 bool load_map = false;
640 661
662 al->machine = machine;
641 al->thread = thread; 663 al->thread = thread;
642 al->addr = addr; 664 al->addr = addr;
643 al->cpumode = cpumode; 665 al->cpumode = cpumode;
@@ -658,15 +680,10 @@ void thread__find_addr_map(struct thread *thread,
658 al->level = 'g'; 680 al->level = 'g';
659 mg = &machine->kmaps; 681 mg = &machine->kmaps;
660 load_map = true; 682 load_map = true;
683 } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) {
684 al->level = 'u';
661 } else { 685 } else {
662 /* 686 al->level = 'H';
663 * 'u' means guest os user space.
664 * TODO: We don't support guest user space. Might support late.
665 */
666 if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest)
667 al->level = 'u';
668 else
669 al->level = 'H';
670 al->map = NULL; 687 al->map = NULL;
671 688
672 if ((cpumode == PERF_RECORD_MISC_GUEST_USER || 689 if ((cpumode == PERF_RECORD_MISC_GUEST_USER ||
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index da3182914984..b08a7ecdcea1 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -101,10 +101,8 @@ static void perf_evlist__purge(struct perf_evlist *evlist)
101 101
102void perf_evlist__exit(struct perf_evlist *evlist) 102void perf_evlist__exit(struct perf_evlist *evlist)
103{ 103{
104 free(evlist->mmap); 104 zfree(&evlist->mmap);
105 free(evlist->pollfd); 105 zfree(&evlist->pollfd);
106 evlist->mmap = NULL;
107 evlist->pollfd = NULL;
108} 106}
109 107
110void perf_evlist__delete(struct perf_evlist *evlist) 108void perf_evlist__delete(struct perf_evlist *evlist)
@@ -587,8 +585,7 @@ void perf_evlist__munmap(struct perf_evlist *evlist)
587 for (i = 0; i < evlist->nr_mmaps; i++) 585 for (i = 0; i < evlist->nr_mmaps; i++)
588 __perf_evlist__munmap(evlist, i); 586 __perf_evlist__munmap(evlist, i);
589 587
590 free(evlist->mmap); 588 zfree(&evlist->mmap);
591 evlist->mmap = NULL;
592} 589}
593 590
594static int perf_evlist__alloc_mmap(struct perf_evlist *evlist) 591static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 9f64ede3ecbd..2fe51958ed85 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -12,7 +12,7 @@
12struct pollfd; 12struct pollfd;
13struct thread_map; 13struct thread_map;
14struct cpu_map; 14struct cpu_map;
15struct perf_record_opts; 15struct record_opts;
16 16
17#define PERF_EVLIST__HLIST_BITS 8 17#define PERF_EVLIST__HLIST_BITS 8
18#define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) 18#define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS)
@@ -97,9 +97,8 @@ void perf_evlist__close(struct perf_evlist *evlist);
97 97
98void perf_evlist__set_id_pos(struct perf_evlist *evlist); 98void perf_evlist__set_id_pos(struct perf_evlist *evlist);
99bool perf_can_sample_identifier(void); 99bool perf_can_sample_identifier(void);
100void perf_evlist__config(struct perf_evlist *evlist, 100void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts);
101 struct perf_record_opts *opts); 101int record_opts__config(struct record_opts *opts);
102int perf_record_opts__config(struct perf_record_opts *opts);
103 102
104int perf_evlist__prepare_workload(struct perf_evlist *evlist, 103int perf_evlist__prepare_workload(struct perf_evlist *evlist,
105 struct target *target, 104 struct target *target,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 01ff4cfde1f5..ade8d9c1c431 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -208,7 +208,7 @@ struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int
208 return evsel; 208 return evsel;
209 209
210out_free: 210out_free:
211 free(evsel->name); 211 zfree(&evsel->name);
212 free(evsel); 212 free(evsel);
213 return NULL; 213 return NULL;
214} 214}
@@ -528,8 +528,7 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
528 * enable/disable events specifically, as there's no 528 * enable/disable events specifically, as there's no
529 * initial traced exec call. 529 * initial traced exec call.
530 */ 530 */
531void perf_evsel__config(struct perf_evsel *evsel, 531void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
532 struct perf_record_opts *opts)
533{ 532{
534 struct perf_evsel *leader = evsel->leader; 533 struct perf_evsel *leader = evsel->leader;
535 struct perf_event_attr *attr = &evsel->attr; 534 struct perf_event_attr *attr = &evsel->attr;
@@ -751,8 +750,7 @@ void perf_evsel__free_id(struct perf_evsel *evsel)
751{ 750{
752 xyarray__delete(evsel->sample_id); 751 xyarray__delete(evsel->sample_id);
753 evsel->sample_id = NULL; 752 evsel->sample_id = NULL;
754 free(evsel->id); 753 zfree(&evsel->id);
755 evsel->id = NULL;
756} 754}
757 755
758void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) 756void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
@@ -768,7 +766,7 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
768 766
769void perf_evsel__free_counts(struct perf_evsel *evsel) 767void perf_evsel__free_counts(struct perf_evsel *evsel)
770{ 768{
771 free(evsel->counts); 769 zfree(&evsel->counts);
772} 770}
773 771
774void perf_evsel__exit(struct perf_evsel *evsel) 772void perf_evsel__exit(struct perf_evsel *evsel)
@@ -782,10 +780,10 @@ void perf_evsel__delete(struct perf_evsel *evsel)
782{ 780{
783 perf_evsel__exit(evsel); 781 perf_evsel__exit(evsel);
784 close_cgroup(evsel->cgrp); 782 close_cgroup(evsel->cgrp);
785 free(evsel->group_name); 783 zfree(&evsel->group_name);
786 if (evsel->tp_format) 784 if (evsel->tp_format)
787 pevent_free_format(evsel->tp_format); 785 pevent_free_format(evsel->tp_format);
788 free(evsel->name); 786 zfree(&evsel->name);
789 free(evsel); 787 free(evsel);
790} 788}
791 789
@@ -1961,8 +1959,7 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
1961 evsel->attr.type = PERF_TYPE_SOFTWARE; 1959 evsel->attr.type = PERF_TYPE_SOFTWARE;
1962 evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK; 1960 evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK;
1963 1961
1964 free(evsel->name); 1962 zfree(&evsel->name);
1965 evsel->name = NULL;
1966 return true; 1963 return true;
1967 } 1964 }
1968 1965
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 8120eeb86ac1..f1b325665aae 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -96,7 +96,7 @@ struct perf_evsel {
96struct cpu_map; 96struct cpu_map;
97struct thread_map; 97struct thread_map;
98struct perf_evlist; 98struct perf_evlist;
99struct perf_record_opts; 99struct record_opts;
100 100
101struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); 101struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx);
102 102
@@ -120,7 +120,7 @@ void perf_evsel__exit(struct perf_evsel *evsel);
120void perf_evsel__delete(struct perf_evsel *evsel); 120void perf_evsel__delete(struct perf_evsel *evsel);
121 121
122void perf_evsel__config(struct perf_evsel *evsel, 122void perf_evsel__config(struct perf_evsel *evsel,
123 struct perf_record_opts *opts); 123 struct record_opts *opts);
124 124
125int __perf_evsel__sample_size(u64 sample_type); 125int __perf_evsel__sample_size(u64 sample_type);
126void perf_evsel__calc_id_pos(struct perf_evsel *evsel); 126void perf_evsel__calc_id_pos(struct perf_evsel *evsel);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 61c54213704b..a4a60b7887ee 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -800,10 +800,10 @@ static void free_cpu_topo(struct cpu_topo *tp)
800 return; 800 return;
801 801
802 for (i = 0 ; i < tp->core_sib; i++) 802 for (i = 0 ; i < tp->core_sib; i++)
803 free(tp->core_siblings[i]); 803 zfree(&tp->core_siblings[i]);
804 804
805 for (i = 0 ; i < tp->thread_sib; i++) 805 for (i = 0 ; i < tp->thread_sib; i++)
806 free(tp->thread_siblings[i]); 806 zfree(&tp->thread_siblings[i]);
807 807
808 free(tp); 808 free(tp);
809} 809}
@@ -1232,10 +1232,8 @@ static void free_event_desc(struct perf_evsel *events)
1232 return; 1232 return;
1233 1233
1234 for (evsel = events; evsel->attr.size; evsel++) { 1234 for (evsel = events; evsel->attr.size; evsel++) {
1235 if (evsel->name) 1235 zfree(&evsel->name);
1236 free(evsel->name); 1236 zfree(&evsel->id);
1237 if (evsel->id)
1238 free(evsel->id);
1239 } 1237 }
1240 1238
1241 free(events); 1239 free(events);
@@ -1326,8 +1324,7 @@ read_event_desc(struct perf_header *ph, int fd)
1326 } 1324 }
1327 } 1325 }
1328out: 1326out:
1329 if (buf) 1327 free(buf);
1330 free(buf);
1331 return events; 1328 return events;
1332error: 1329error:
1333 if (events) 1330 if (events)
@@ -2108,7 +2105,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused,
2108 ret = 0; 2105 ret = 0;
2109out_free: 2106out_free:
2110 for (i = 0; i < nr_groups; i++) 2107 for (i = 0; i < nr_groups; i++)
2111 free(desc[i].name); 2108 zfree(&desc[i].name);
2112 free(desc); 2109 free(desc);
2113 2110
2114 return ret; 2111 return ret;
diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c
index 8b1f6e891b8a..86c37c472263 100644
--- a/tools/perf/util/help.c
+++ b/tools/perf/util/help.c
@@ -22,8 +22,8 @@ static void clean_cmdnames(struct cmdnames *cmds)
22 unsigned int i; 22 unsigned int i;
23 23
24 for (i = 0; i < cmds->cnt; ++i) 24 for (i = 0; i < cmds->cnt; ++i)
25 free(cmds->names[i]); 25 zfree(&cmds->names[i]);
26 free(cmds->names); 26 zfree(&cmds->names);
27 cmds->cnt = 0; 27 cmds->cnt = 0;
28 cmds->alloc = 0; 28 cmds->alloc = 0;
29} 29}
@@ -263,9 +263,8 @@ static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)
263 263
264 for (i = 0; i < old->cnt; i++) 264 for (i = 0; i < old->cnt; i++)
265 cmds->names[cmds->cnt++] = old->names[i]; 265 cmds->names[cmds->cnt++] = old->names[i];
266 free(old->names); 266 zfree(&old->names);
267 old->cnt = 0; 267 old->cnt = 0;
268 old->names = NULL;
269} 268}
270 269
271const char *help_unknown_cmd(const char *cmd) 270const char *help_unknown_cmd(const char *cmd)
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 822903eaa201..4ed3e883240d 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1,4 +1,3 @@
1#include "annotate.h"
2#include "util.h" 1#include "util.h"
3#include "build-id.h" 2#include "build-id.h"
4#include "hist.h" 3#include "hist.h"
@@ -342,15 +341,15 @@ static u8 symbol__parent_filter(const struct symbol *parent)
342} 341}
343 342
344static struct hist_entry *add_hist_entry(struct hists *hists, 343static struct hist_entry *add_hist_entry(struct hists *hists,
345 struct hist_entry *entry, 344 struct hist_entry *entry,
346 struct addr_location *al, 345 struct addr_location *al)
347 u64 period,
348 u64 weight)
349{ 346{
350 struct rb_node **p; 347 struct rb_node **p;
351 struct rb_node *parent = NULL; 348 struct rb_node *parent = NULL;
352 struct hist_entry *he; 349 struct hist_entry *he;
353 int64_t cmp; 350 int64_t cmp;
351 u64 period = entry->stat.period;
352 u64 weight = entry->stat.weight;
354 353
355 p = &hists->entries_in->rb_node; 354 p = &hists->entries_in->rb_node;
356 355
@@ -373,7 +372,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
373 * This mem info was allocated from machine__resolve_mem 372 * This mem info was allocated from machine__resolve_mem
374 * and will not be used anymore. 373 * and will not be used anymore.
375 */ 374 */
376 free(entry->mem_info); 375 zfree(&entry->mem_info);
377 376
378 /* If the map of an existing hist_entry has 377 /* If the map of an existing hist_entry has
379 * become out-of-date due to an exec() or 378 * become out-of-date due to an exec() or
@@ -437,7 +436,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
437 .transaction = transaction, 436 .transaction = transaction,
438 }; 437 };
439 438
440 return add_hist_entry(hists, &entry, al, period, weight); 439 return add_hist_entry(hists, &entry, al);
441} 440}
442 441
443int64_t 442int64_t
@@ -476,8 +475,8 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
476 475
477void hist_entry__free(struct hist_entry *he) 476void hist_entry__free(struct hist_entry *he)
478{ 477{
479 free(he->branch_info); 478 zfree(&he->branch_info);
480 free(he->mem_info); 479 zfree(&he->mem_info);
481 free_srcline(he->srcline); 480 free_srcline(he->srcline);
482 free(he); 481 free(he);
483} 482}
@@ -807,16 +806,6 @@ void hists__filter_by_symbol(struct hists *hists)
807 } 806 }
808} 807}
809 808
810int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip)
811{
812 return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip);
813}
814
815int hist_entry__annotate(struct hist_entry *he, size_t privsize)
816{
817 return symbol__annotate(he->ms.sym, he->ms.map, privsize);
818}
819
820void events_stats__inc(struct events_stats *stats, u32 type) 809void events_stats__inc(struct events_stats *stats, u32 type)
821{ 810{
822 ++stats->nr_events[0]; 811 ++stats->nr_events[0];
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index b621347a1585..a59743fa3ef7 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -111,9 +111,6 @@ size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
111size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, 111size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
112 int max_cols, float min_pcnt, FILE *fp); 112 int max_cols, float min_pcnt, FILE *fp);
113 113
114int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
115int hist_entry__annotate(struct hist_entry *he, size_t privsize);
116
117void hists__filter_by_dso(struct hists *hists); 114void hists__filter_by_dso(struct hists *hists);
118void hists__filter_by_thread(struct hists *hists); 115void hists__filter_by_thread(struct hists *hists);
119void hists__filter_by_symbol(struct hists *hists); 116void hists__filter_by_symbol(struct hists *hists);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index c78cc84f433e..a98538dc465a 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -102,8 +102,7 @@ void machine__exit(struct machine *machine)
102 map_groups__exit(&machine->kmaps); 102 map_groups__exit(&machine->kmaps);
103 dsos__delete(&machine->user_dsos); 103 dsos__delete(&machine->user_dsos);
104 dsos__delete(&machine->kernel_dsos); 104 dsos__delete(&machine->kernel_dsos);
105 free(machine->root_dir); 105 zfree(&machine->root_dir);
106 machine->root_dir = NULL;
107} 106}
108 107
109void machine__delete(struct machine *machine) 108void machine__delete(struct machine *machine)
@@ -562,11 +561,10 @@ void machine__destroy_kernel_maps(struct machine *machine)
562 * on one of them. 561 * on one of them.
563 */ 562 */
564 if (type == MAP__FUNCTION) { 563 if (type == MAP__FUNCTION) {
565 free((char *)kmap->ref_reloc_sym->name); 564 zfree((char **)&kmap->ref_reloc_sym->name);
566 kmap->ref_reloc_sym->name = NULL; 565 zfree(&kmap->ref_reloc_sym);
567 free(kmap->ref_reloc_sym); 566 } else
568 } 567 kmap->ref_reloc_sym = NULL;
569 kmap->ref_reloc_sym = NULL;
570 } 568 }
571 569
572 map__delete(machine->vmlinux_maps[type]); 570 map__delete(machine->vmlinux_maps[type]);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 094c28ba2fae..0153435b8427 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -204,7 +204,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
204 } 204 }
205 path->name = malloc(MAX_EVENT_LENGTH); 205 path->name = malloc(MAX_EVENT_LENGTH);
206 if (!path->name) { 206 if (!path->name) {
207 free(path->system); 207 zfree(&path->system);
208 free(path); 208 free(path);
209 return NULL; 209 return NULL;
210 } 210 }
@@ -236,8 +236,8 @@ struct tracepoint_path *tracepoint_name_to_path(const char *name)
236 path->name = strdup(str+1); 236 path->name = strdup(str+1);
237 237
238 if (path->system == NULL || path->name == NULL) { 238 if (path->system == NULL || path->name == NULL) {
239 free(path->system); 239 zfree(&path->system);
240 free(path->name); 240 zfree(&path->name);
241 free(path); 241 free(path);
242 path = NULL; 242 path = NULL;
243 } 243 }
@@ -917,7 +917,7 @@ int parse_events_terms(struct list_head *terms, const char *str)
917 ret = parse_events__scanner(str, &data, PE_START_TERMS); 917 ret = parse_events__scanner(str, &data, PE_START_TERMS);
918 if (!ret) { 918 if (!ret) {
919 list_splice(data.terms, terms); 919 list_splice(data.terms, terms);
920 free(data.terms); 920 zfree(&data.terms);
921 return 0; 921 return 0;
922 } 922 }
923 923
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 56fc10a5e288..0934d645ebdc 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -755,7 +755,7 @@ void print_pmu_events(const char *event_glob, bool name_only)
755 continue; 755 continue;
756 } 756 }
757 printf(" %-50s [Kernel PMU event]\n", aliases[j]); 757 printf(" %-50s [Kernel PMU event]\n", aliases[j]);
758 free(aliases[j]); 758 zfree(&aliases[j]);
759 printed++; 759 printed++;
760 } 760 }
761 if (printed) 761 if (printed)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 544ac1898a9f..86ed8580c3cb 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -172,6 +172,52 @@ const char *kernel_get_module_path(const char *module)
172 return (dso) ? dso->long_name : NULL; 172 return (dso) ? dso->long_name : NULL;
173} 173}
174 174
175/* Copied from unwind.c */
176static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
177 GElf_Shdr *shp, const char *name)
178{
179 Elf_Scn *sec = NULL;
180
181 while ((sec = elf_nextscn(elf, sec)) != NULL) {
182 char *str;
183
184 gelf_getshdr(sec, shp);
185 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
186 if (!strcmp(name, str))
187 break;
188 }
189
190 return sec;
191}
192
193static int get_text_start_address(const char *exec, unsigned long *address)
194{
195 Elf *elf;
196 GElf_Ehdr ehdr;
197 GElf_Shdr shdr;
198 int fd, ret = -ENOENT;
199
200 fd = open(exec, O_RDONLY);
201 if (fd < 0)
202 return -errno;
203
204 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
205 if (elf == NULL)
206 return -EINVAL;
207
208 if (gelf_getehdr(elf, &ehdr) == NULL)
209 goto out;
210
211 if (!elf_section_by_name(elf, &ehdr, &shdr, ".text"))
212 goto out;
213
214 *address = shdr.sh_addr - shdr.sh_offset;
215 ret = 0;
216out:
217 elf_end(elf);
218 return ret;
219}
220
175static int init_user_exec(void) 221static int init_user_exec(void)
176{ 222{
177 int ret = 0; 223 int ret = 0;
@@ -186,6 +232,37 @@ static int init_user_exec(void)
186 return ret; 232 return ret;
187} 233}
188 234
235static int convert_exec_to_group(const char *exec, char **result)
236{
237 char *ptr1, *ptr2, *exec_copy;
238 char buf[64];
239 int ret;
240
241 exec_copy = strdup(exec);
242 if (!exec_copy)
243 return -ENOMEM;
244
245 ptr1 = basename(exec_copy);
246 if (!ptr1) {
247 ret = -EINVAL;
248 goto out;
249 }
250
251 ptr2 = strpbrk(ptr1, "-._");
252 if (ptr2)
253 *ptr2 = '\0';
254 ret = e_snprintf(buf, 64, "%s_%s", PERFPROBE_GROUP, ptr1);
255 if (ret < 0)
256 goto out;
257
258 *result = strdup(buf);
259 ret = *result ? 0 : -ENOMEM;
260
261out:
262 free(exec_copy);
263 return ret;
264}
265
189static int convert_to_perf_probe_point(struct probe_trace_point *tp, 266static int convert_to_perf_probe_point(struct probe_trace_point *tp,
190 struct perf_probe_point *pp) 267 struct perf_probe_point *pp)
191{ 268{
@@ -261,6 +338,40 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
261 return 0; 338 return 0;
262} 339}
263 340
341static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,
342 int ntevs, const char *exec)
343{
344 int i, ret = 0;
345 unsigned long offset, stext = 0;
346 char buf[32];
347
348 if (!exec)
349 return 0;
350
351 ret = get_text_start_address(exec, &stext);
352 if (ret < 0)
353 return ret;
354
355 for (i = 0; i < ntevs && ret >= 0; i++) {
356 offset = tevs[i].point.address - stext;
357 offset += tevs[i].point.offset;
358 tevs[i].point.offset = 0;
359 zfree(&tevs[i].point.symbol);
360 ret = e_snprintf(buf, 32, "0x%lx", offset);
361 if (ret < 0)
362 break;
363 tevs[i].point.module = strdup(exec);
364 tevs[i].point.symbol = strdup(buf);
365 if (!tevs[i].point.symbol || !tevs[i].point.module) {
366 ret = -ENOMEM;
367 break;
368 }
369 tevs[i].uprobes = true;
370 }
371
372 return ret;
373}
374
264static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, 375static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
265 int ntevs, const char *module) 376 int ntevs, const char *module)
266{ 377{
@@ -290,9 +401,7 @@ static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
290 } 401 }
291 } 402 }
292 403
293 if (tmp) 404 free(tmp);
294 free(tmp);
295
296 return ret; 405 return ret;
297} 406}
298 407
@@ -305,15 +414,6 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
305 struct debuginfo *dinfo; 414 struct debuginfo *dinfo;
306 int ntevs, ret = 0; 415 int ntevs, ret = 0;
307 416
308 if (pev->uprobes) {
309 if (need_dwarf) {
310 pr_warning("Debuginfo-analysis is not yet supported"
311 " with -x/--exec option.\n");
312 return -ENOSYS;
313 }
314 return convert_name_to_addr(pev, target);
315 }
316
317 dinfo = open_debuginfo(target); 417 dinfo = open_debuginfo(target);
318 418
319 if (!dinfo) { 419 if (!dinfo) {
@@ -332,9 +432,14 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
332 432
333 if (ntevs > 0) { /* Succeeded to find trace events */ 433 if (ntevs > 0) { /* Succeeded to find trace events */
334 pr_debug("find %d probe_trace_events.\n", ntevs); 434 pr_debug("find %d probe_trace_events.\n", ntevs);
335 if (target) 435 if (target) {
336 ret = add_module_to_probe_trace_events(*tevs, ntevs, 436 if (pev->uprobes)
337 target); 437 ret = add_exec_to_probe_trace_events(*tevs,
438 ntevs, target);
439 else
440 ret = add_module_to_probe_trace_events(*tevs,
441 ntevs, target);
442 }
338 return ret < 0 ? ret : ntevs; 443 return ret < 0 ? ret : ntevs;
339 } 444 }
340 445
@@ -401,15 +506,13 @@ static int get_real_path(const char *raw_path, const char *comp_dir,
401 case EFAULT: 506 case EFAULT:
402 raw_path = strchr(++raw_path, '/'); 507 raw_path = strchr(++raw_path, '/');
403 if (!raw_path) { 508 if (!raw_path) {
404 free(*new_path); 509 zfree(new_path);
405 *new_path = NULL;
406 return -ENOENT; 510 return -ENOENT;
407 } 511 }
408 continue; 512 continue;
409 513
410 default: 514 default:
411 free(*new_path); 515 zfree(new_path);
412 *new_path = NULL;
413 return -errno; 516 return -errno;
414 } 517 }
415 } 518 }
@@ -580,7 +683,7 @@ static int show_available_vars_at(struct debuginfo *dinfo,
580 */ 683 */
581 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, 684 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol,
582 vl->point.offset); 685 vl->point.offset);
583 free(vl->point.symbol); 686 zfree(&vl->point.symbol);
584 nvars = 0; 687 nvars = 0;
585 if (vl->vars) { 688 if (vl->vars) {
586 strlist__for_each(node, vl->vars) { 689 strlist__for_each(node, vl->vars) {
@@ -654,9 +757,6 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
654 return -ENOSYS; 757 return -ENOSYS;
655 } 758 }
656 759
657 if (pev->uprobes)
658 return convert_name_to_addr(pev, target);
659
660 return 0; 760 return 0;
661} 761}
662 762
@@ -1278,8 +1378,7 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
1278error: 1378error:
1279 pr_debug("Failed to synthesize perf probe point: %s\n", 1379 pr_debug("Failed to synthesize perf probe point: %s\n",
1280 strerror(-ret)); 1380 strerror(-ret));
1281 if (buf) 1381 free(buf);
1282 free(buf);
1283 return NULL; 1382 return NULL;
1284} 1383}
1285 1384
@@ -1480,34 +1579,25 @@ void clear_perf_probe_event(struct perf_probe_event *pev)
1480 struct perf_probe_arg_field *field, *next; 1579 struct perf_probe_arg_field *field, *next;
1481 int i; 1580 int i;
1482 1581
1483 if (pev->event) 1582 free(pev->event);
1484 free(pev->event); 1583 free(pev->group);
1485 if (pev->group) 1584 free(pp->file);
1486 free(pev->group); 1585 free(pp->function);
1487 if (pp->file) 1586 free(pp->lazy_line);
1488 free(pp->file); 1587
1489 if (pp->function)
1490 free(pp->function);
1491 if (pp->lazy_line)
1492 free(pp->lazy_line);
1493 for (i = 0; i < pev->nargs; i++) { 1588 for (i = 0; i < pev->nargs; i++) {
1494 if (pev->args[i].name) 1589 free(pev->args[i].name);
1495 free(pev->args[i].name); 1590 free(pev->args[i].var);
1496 if (pev->args[i].var) 1591 free(pev->args[i].type);
1497 free(pev->args[i].var);
1498 if (pev->args[i].type)
1499 free(pev->args[i].type);
1500 field = pev->args[i].field; 1592 field = pev->args[i].field;
1501 while (field) { 1593 while (field) {
1502 next = field->next; 1594 next = field->next;
1503 if (field->name) 1595 zfree(&field->name);
1504 free(field->name);
1505 free(field); 1596 free(field);
1506 field = next; 1597 field = next;
1507 } 1598 }
1508 } 1599 }
1509 if (pev->args) 1600 free(pev->args);
1510 free(pev->args);
1511 memset(pev, 0, sizeof(*pev)); 1601 memset(pev, 0, sizeof(*pev));
1512} 1602}
1513 1603
@@ -1516,21 +1606,14 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)
1516 struct probe_trace_arg_ref *ref, *next; 1606 struct probe_trace_arg_ref *ref, *next;
1517 int i; 1607 int i;
1518 1608
1519 if (tev->event) 1609 free(tev->event);
1520 free(tev->event); 1610 free(tev->group);
1521 if (tev->group) 1611 free(tev->point.symbol);
1522 free(tev->group); 1612 free(tev->point.module);
1523 if (tev->point.symbol)
1524 free(tev->point.symbol);
1525 if (tev->point.module)
1526 free(tev->point.module);
1527 for (i = 0; i < tev->nargs; i++) { 1613 for (i = 0; i < tev->nargs; i++) {
1528 if (tev->args[i].name) 1614 free(tev->args[i].name);
1529 free(tev->args[i].name); 1615 free(tev->args[i].value);
1530 if (tev->args[i].value) 1616 free(tev->args[i].type);
1531 free(tev->args[i].value);
1532 if (tev->args[i].type)
1533 free(tev->args[i].type);
1534 ref = tev->args[i].ref; 1617 ref = tev->args[i].ref;
1535 while (ref) { 1618 while (ref) {
1536 next = ref->next; 1619 next = ref->next;
@@ -1538,8 +1621,7 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)
1538 ref = next; 1621 ref = next;
1539 } 1622 }
1540 } 1623 }
1541 if (tev->args) 1624 free(tev->args);
1542 free(tev->args);
1543 memset(tev, 0, sizeof(*tev)); 1625 memset(tev, 0, sizeof(*tev));
1544} 1626}
1545 1627
@@ -1913,14 +1995,29 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
1913 int max_tevs, const char *target) 1995 int max_tevs, const char *target)
1914{ 1996{
1915 struct symbol *sym; 1997 struct symbol *sym;
1916 int ret = 0, i; 1998 int ret, i;
1917 struct probe_trace_event *tev; 1999 struct probe_trace_event *tev;
1918 2000
2001 if (pev->uprobes && !pev->group) {
2002 /* Replace group name if not given */
2003 ret = convert_exec_to_group(target, &pev->group);
2004 if (ret != 0) {
2005 pr_warning("Failed to make a group name.\n");
2006 return ret;
2007 }
2008 }
2009
1919 /* Convert perf_probe_event with debuginfo */ 2010 /* Convert perf_probe_event with debuginfo */
1920 ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target); 2011 ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target);
1921 if (ret != 0) 2012 if (ret != 0)
1922 return ret; /* Found in debuginfo or got an error */ 2013 return ret; /* Found in debuginfo or got an error */
1923 2014
2015 if (pev->uprobes) {
2016 ret = convert_name_to_addr(pev, target);
2017 if (ret < 0)
2018 return ret;
2019 }
2020
1924 /* Allocate trace event buffer */ 2021 /* Allocate trace event buffer */
1925 tev = *tevs = zalloc(sizeof(struct probe_trace_event)); 2022 tev = *tevs = zalloc(sizeof(struct probe_trace_event));
1926 if (tev == NULL) 2023 if (tev == NULL)
@@ -2056,7 +2153,7 @@ end:
2056 for (i = 0; i < npevs; i++) { 2153 for (i = 0; i < npevs; i++) {
2057 for (j = 0; j < pkgs[i].ntevs; j++) 2154 for (j = 0; j < pkgs[i].ntevs; j++)
2058 clear_probe_trace_event(&pkgs[i].tevs[j]); 2155 clear_probe_trace_event(&pkgs[i].tevs[j]);
2059 free(pkgs[i].tevs); 2156 zfree(&pkgs[i].tevs);
2060 } 2157 }
2061 free(pkgs); 2158 free(pkgs);
2062 2159
@@ -2281,7 +2378,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
2281 struct perf_probe_point *pp = &pev->point; 2378 struct perf_probe_point *pp = &pev->point;
2282 struct symbol *sym; 2379 struct symbol *sym;
2283 struct map *map = NULL; 2380 struct map *map = NULL;
2284 char *function = NULL, *name = NULL; 2381 char *function = NULL;
2285 int ret = -EINVAL; 2382 int ret = -EINVAL;
2286 unsigned long long vaddr = 0; 2383 unsigned long long vaddr = 0;
2287 2384
@@ -2297,12 +2394,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
2297 goto out; 2394 goto out;
2298 } 2395 }
2299 2396
2300 name = realpath(exec, NULL); 2397 map = dso__new_map(exec);
2301 if (!name) {
2302 pr_warning("Cannot find realpath for %s.\n", exec);
2303 goto out;
2304 }
2305 map = dso__new_map(name);
2306 if (!map) { 2398 if (!map) {
2307 pr_warning("Cannot find appropriate DSO for %s.\n", exec); 2399 pr_warning("Cannot find appropriate DSO for %s.\n", exec);
2308 goto out; 2400 goto out;
@@ -2367,7 +2459,5 @@ out:
2367 } 2459 }
2368 if (function) 2460 if (function)
2369 free(function); 2461 free(function);
2370 if (name)
2371 free(name);
2372 return ret; 2462 return ret;
2373} 2463}
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index f9f3de8b4220..d481c46e0796 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -12,6 +12,7 @@ struct probe_trace_point {
12 char *symbol; /* Base symbol */ 12 char *symbol; /* Base symbol */
13 char *module; /* Module name */ 13 char *module; /* Module name */
14 unsigned long offset; /* Offset from symbol */ 14 unsigned long offset; /* Offset from symbol */
15 unsigned long address; /* Actual address of the trace point */
15 bool retprobe; /* Return probe flag */ 16 bool retprobe; /* Return probe flag */
16}; 17};
17 18
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index ffb657ffd327..061edb162b5b 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -226,10 +226,8 @@ struct debuginfo *debuginfo__new(const char *path)
226 if (!dbg) 226 if (!dbg)
227 return NULL; 227 return NULL;
228 228
229 if (debuginfo__init_offline_dwarf(dbg, path) < 0) { 229 if (debuginfo__init_offline_dwarf(dbg, path) < 0)
230 free(dbg); 230 zfree(&dbg);
231 dbg = NULL;
232 }
233 231
234 return dbg; 232 return dbg;
235} 233}
@@ -241,10 +239,8 @@ struct debuginfo *debuginfo__new_online_kernel(unsigned long addr)
241 if (!dbg) 239 if (!dbg)
242 return NULL; 240 return NULL;
243 241
244 if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0) { 242 if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0)
245 free(dbg); 243 zfree(&dbg);
246 dbg = NULL;
247 }
248 244
249 return dbg; 245 return dbg;
250} 246}
@@ -729,6 +725,7 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
729 return -ENOENT; 725 return -ENOENT;
730 } 726 }
731 tp->offset = (unsigned long)(paddr - sym.st_value); 727 tp->offset = (unsigned long)(paddr - sym.st_value);
728 tp->address = (unsigned long)paddr;
732 tp->symbol = strdup(symbol); 729 tp->symbol = strdup(symbol);
733 if (!tp->symbol) 730 if (!tp->symbol)
734 return -ENOMEM; 731 return -ENOMEM;
@@ -1301,8 +1298,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
1301 1298
1302 ret = debuginfo__find_probes(dbg, &tf.pf); 1299 ret = debuginfo__find_probes(dbg, &tf.pf);
1303 if (ret < 0) { 1300 if (ret < 0) {
1304 free(*tevs); 1301 zfree(tevs);
1305 *tevs = NULL;
1306 return ret; 1302 return ret;
1307 } 1303 }
1308 1304
@@ -1413,13 +1409,10 @@ int debuginfo__find_available_vars_at(struct debuginfo *dbg,
1413 if (ret < 0) { 1409 if (ret < 0) {
1414 /* Free vlist for error */ 1410 /* Free vlist for error */
1415 while (af.nvls--) { 1411 while (af.nvls--) {
1416 if (af.vls[af.nvls].point.symbol) 1412 zfree(&af.vls[af.nvls].point.symbol);
1417 free(af.vls[af.nvls].point.symbol); 1413 strlist__delete(af.vls[af.nvls].vars);
1418 if (af.vls[af.nvls].vars)
1419 strlist__delete(af.vls[af.nvls].vars);
1420 } 1414 }
1421 free(af.vls); 1415 zfree(vls);
1422 *vls = NULL;
1423 return ret; 1416 return ret;
1424 } 1417 }
1425 1418
@@ -1523,10 +1516,7 @@ post:
1523 if (fname) { 1516 if (fname) {
1524 ppt->file = strdup(fname); 1517 ppt->file = strdup(fname);
1525 if (ppt->file == NULL) { 1518 if (ppt->file == NULL) {
1526 if (ppt->function) { 1519 zfree(&ppt->function);
1527 free(ppt->function);
1528 ppt->function = NULL;
1529 }
1530 ret = -ENOMEM; 1520 ret = -ENOMEM;
1531 goto end; 1521 goto end;
1532 } 1522 }
@@ -1580,8 +1570,7 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
1580 else 1570 else
1581 ret = 0; /* Lines are not found */ 1571 ret = 0; /* Lines are not found */
1582 else { 1572 else {
1583 free(lf->lr->path); 1573 zfree(&lf->lr->path);
1584 lf->lr->path = NULL;
1585 } 1574 }
1586 return ret; 1575 return ret;
1587} 1576}
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index e5104538c354..104a47563d39 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -74,8 +74,7 @@ bool perf_can_sample_identifier(void)
74 return perf_probe_api(perf_probe_sample_identifier); 74 return perf_probe_api(perf_probe_sample_identifier);
75} 75}
76 76
77void perf_evlist__config(struct perf_evlist *evlist, 77void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
78 struct perf_record_opts *opts)
79{ 78{
80 struct perf_evsel *evsel; 79 struct perf_evsel *evsel;
81 bool use_sample_identifier = false; 80 bool use_sample_identifier = false;
@@ -123,7 +122,7 @@ static int get_max_rate(unsigned int *rate)
123 return filename__read_int(path, (int *) rate); 122 return filename__read_int(path, (int *) rate);
124} 123}
125 124
126static int perf_record_opts__config_freq(struct perf_record_opts *opts) 125static int record_opts__config_freq(struct record_opts *opts)
127{ 126{
128 bool user_freq = opts->user_freq != UINT_MAX; 127 bool user_freq = opts->user_freq != UINT_MAX;
129 unsigned int max_rate; 128 unsigned int max_rate;
@@ -173,9 +172,9 @@ static int perf_record_opts__config_freq(struct perf_record_opts *opts)
173 return 0; 172 return 0;
174} 173}
175 174
176int perf_record_opts__config(struct perf_record_opts *opts) 175int record_opts__config(struct record_opts *opts)
177{ 176{
178 return perf_record_opts__config_freq(opts); 177 return record_opts__config_freq(opts);
179} 178}
180 179
181bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) 180bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index d5e5969f6fea..e108207c5de0 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -194,8 +194,7 @@ static void define_event_symbols(struct event_format *event,
194 zero_flag_atom = 0; 194 zero_flag_atom = 0;
195 break; 195 break;
196 case PRINT_FIELD: 196 case PRINT_FIELD:
197 if (cur_field_name) 197 free(cur_field_name);
198 free(cur_field_name);
199 cur_field_name = strdup(args->field.name); 198 cur_field_name = strdup(args->field.name);
200 break; 199 break;
201 case PRINT_FLAGS: 200 case PRINT_FLAGS:
@@ -257,12 +256,9 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
257 return event; 256 return event;
258} 257}
259 258
260static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused, 259static void perl_process_tracepoint(struct perf_sample *sample,
261 struct perf_sample *sample,
262 struct perf_evsel *evsel, 260 struct perf_evsel *evsel,
263 struct machine *machine __maybe_unused, 261 struct thread *thread)
264 struct thread *thread,
265 struct addr_location *al)
266{ 262{
267 struct format_field *field; 263 struct format_field *field;
268 static char handler[256]; 264 static char handler[256];
@@ -349,10 +345,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
349 345
350static void perl_process_event_generic(union perf_event *event, 346static void perl_process_event_generic(union perf_event *event,
351 struct perf_sample *sample, 347 struct perf_sample *sample,
352 struct perf_evsel *evsel, 348 struct perf_evsel *evsel)
353 struct machine *machine __maybe_unused,
354 struct thread *thread __maybe_unused,
355 struct addr_location *al __maybe_unused)
356{ 349{
357 dSP; 350 dSP;
358 351
@@ -377,12 +370,11 @@ static void perl_process_event_generic(union perf_event *event,
377static void perl_process_event(union perf_event *event, 370static void perl_process_event(union perf_event *event,
378 struct perf_sample *sample, 371 struct perf_sample *sample,
379 struct perf_evsel *evsel, 372 struct perf_evsel *evsel,
380 struct machine *machine,
381 struct thread *thread, 373 struct thread *thread,
382 struct addr_location *al) 374 struct addr_location *al __maybe_unused)
383{ 375{
384 perl_process_tracepoint(event, sample, evsel, machine, thread, al); 376 perl_process_tracepoint(sample, evsel, thread);
385 perl_process_event_generic(event, sample, evsel, machine, thread, al); 377 perl_process_event_generic(event, sample, evsel);
386} 378}
387 379
388static void run_start_sub(void) 380static void run_start_sub(void)
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 53c20e7fd900..cd9774df3750 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -161,8 +161,7 @@ static void define_event_symbols(struct event_format *event,
161 zero_flag_atom = 0; 161 zero_flag_atom = 0;
162 break; 162 break;
163 case PRINT_FIELD: 163 case PRINT_FIELD:
164 if (cur_field_name) 164 free(cur_field_name);
165 free(cur_field_name);
166 cur_field_name = strdup(args->field.name); 165 cur_field_name = strdup(args->field.name);
167 break; 166 break;
168 case PRINT_FLAGS: 167 case PRINT_FLAGS:
@@ -231,13 +230,10 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
231 return event; 230 return event;
232} 231}
233 232
234static void python_process_tracepoint(union perf_event *perf_event 233static void python_process_tracepoint(struct perf_sample *sample,
235 __maybe_unused, 234 struct perf_evsel *evsel,
236 struct perf_sample *sample, 235 struct thread *thread,
237 struct perf_evsel *evsel, 236 struct addr_location *al)
238 struct machine *machine __maybe_unused,
239 struct thread *thread,
240 struct addr_location *al)
241{ 237{
242 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; 238 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
243 static char handler_name[256]; 239 static char handler_name[256];
@@ -351,11 +347,8 @@ static void python_process_tracepoint(union perf_event *perf_event
351 Py_DECREF(t); 347 Py_DECREF(t);
352} 348}
353 349
354static void python_process_general_event(union perf_event *perf_event 350static void python_process_general_event(struct perf_sample *sample,
355 __maybe_unused,
356 struct perf_sample *sample,
357 struct perf_evsel *evsel, 351 struct perf_evsel *evsel,
358 struct machine *machine __maybe_unused,
359 struct thread *thread, 352 struct thread *thread,
360 struct addr_location *al) 353 struct addr_location *al)
361{ 354{
@@ -411,22 +404,19 @@ exit:
411 Py_DECREF(t); 404 Py_DECREF(t);
412} 405}
413 406
414static void python_process_event(union perf_event *perf_event, 407static void python_process_event(union perf_event *event __maybe_unused,
415 struct perf_sample *sample, 408 struct perf_sample *sample,
416 struct perf_evsel *evsel, 409 struct perf_evsel *evsel,
417 struct machine *machine,
418 struct thread *thread, 410 struct thread *thread,
419 struct addr_location *al) 411 struct addr_location *al)
420{ 412{
421 switch (evsel->attr.type) { 413 switch (evsel->attr.type) {
422 case PERF_TYPE_TRACEPOINT: 414 case PERF_TYPE_TRACEPOINT:
423 python_process_tracepoint(perf_event, sample, evsel, 415 python_process_tracepoint(sample, evsel, thread, al);
424 machine, thread, al);
425 break; 416 break;
426 /* Reserve for future process_hw/sw/raw APIs */ 417 /* Reserve for future process_hw/sw/raw APIs */
427 default: 418 default:
428 python_process_general_event(perf_event, sample, evsel, 419 python_process_general_event(sample, evsel, thread, al);
429 machine, thread, al);
430 } 420 }
431} 421}
432 422
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 989b2e377626..8ffe29c55d0f 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -132,18 +132,18 @@ static void perf_session__delete_threads(struct perf_session *session)
132 132
133static void perf_session_env__delete(struct perf_session_env *env) 133static void perf_session_env__delete(struct perf_session_env *env)
134{ 134{
135 free(env->hostname); 135 zfree(&env->hostname);
136 free(env->os_release); 136 zfree(&env->os_release);
137 free(env->version); 137 zfree(&env->version);
138 free(env->arch); 138 zfree(&env->arch);
139 free(env->cpu_desc); 139 zfree(&env->cpu_desc);
140 free(env->cpuid); 140 zfree(&env->cpuid);
141 141
142 free(env->cmdline); 142 zfree(&env->cmdline);
143 free(env->sibling_cores); 143 zfree(&env->sibling_cores);
144 free(env->sibling_threads); 144 zfree(&env->sibling_threads);
145 free(env->numa_nodes); 145 zfree(&env->numa_nodes);
146 free(env->pmu_mappings); 146 zfree(&env->pmu_mappings);
147} 147}
148 148
149void perf_session__delete(struct perf_session *session) 149void perf_session__delete(struct perf_session *session)
@@ -830,6 +830,7 @@ static struct machine *
830 struct perf_sample *sample) 830 struct perf_sample *sample)
831{ 831{
832 const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 832 const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
833 struct machine *machine;
833 834
834 if (perf_guest && 835 if (perf_guest &&
835 ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || 836 ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) ||
@@ -842,7 +843,11 @@ static struct machine *
842 else 843 else
843 pid = sample->pid; 844 pid = sample->pid;
844 845
845 return perf_session__findnew_machine(session, pid); 846 machine = perf_session__find_machine(session, pid);
847 if (!machine)
848 machine = perf_session__findnew_machine(session,
849 DEFAULT_GUEST_KERNEL_ID);
850 return machine;
846 } 851 }
847 852
848 return &session->machines.host; 853 return &session->machines.host;
@@ -1467,7 +1472,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
1467} 1472}
1468 1473
1469void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, 1474void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
1470 struct machine *machine, struct addr_location *al, 1475 struct addr_location *al,
1471 unsigned int print_opts, unsigned int stack_depth) 1476 unsigned int print_opts, unsigned int stack_depth)
1472{ 1477{
1473 struct callchain_cursor_node *node; 1478 struct callchain_cursor_node *node;
@@ -1482,7 +1487,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
1482 if (symbol_conf.use_callchain && sample->callchain) { 1487 if (symbol_conf.use_callchain && sample->callchain) {
1483 struct addr_location node_al; 1488 struct addr_location node_al;
1484 1489
1485 if (machine__resolve_callchain(machine, evsel, al->thread, 1490 if (machine__resolve_callchain(al->machine, evsel, al->thread,
1486 sample, NULL, NULL, 1491 sample, NULL, NULL,
1487 PERF_MAX_STACK_DEPTH) != 0) { 1492 PERF_MAX_STACK_DEPTH) != 0) {
1488 if (verbose) 1493 if (verbose)
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 9c25d49900af..3140f8ae6148 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -106,7 +106,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
106 unsigned int type); 106 unsigned int type);
107 107
108void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, 108void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
109 struct machine *machine, struct addr_location *al, 109 struct addr_location *al,
110 unsigned int print_opts, unsigned int stack_depth); 110 unsigned int print_opts, unsigned int stack_depth);
111 111
112int perf_session__cpu_bitmap(struct perf_session *session, 112int perf_session__cpu_bitmap(struct perf_session *session,
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 8b0bb1f4494a..635cd8f8b22e 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -13,6 +13,7 @@ int have_ignore_callees = 0;
13int sort__need_collapse = 0; 13int sort__need_collapse = 0;
14int sort__has_parent = 0; 14int sort__has_parent = 0;
15int sort__has_sym = 0; 15int sort__has_sym = 0;
16int sort__has_dso = 0;
16enum sort_mode sort__mode = SORT_MODE__NORMAL; 17enum sort_mode sort__mode = SORT_MODE__NORMAL;
17 18
18enum sort_type sort__first_dimension; 19enum sort_type sort__first_dimension;
@@ -161,6 +162,11 @@ struct sort_entry sort_dso = {
161 162
162/* --sort symbol */ 163/* --sort symbol */
163 164
165static int64_t _sort__addr_cmp(u64 left_ip, u64 right_ip)
166{
167 return (int64_t)(right_ip - left_ip);
168}
169
164static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r) 170static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r)
165{ 171{
166 u64 ip_l, ip_r; 172 u64 ip_l, ip_r;
@@ -183,15 +189,17 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
183 int64_t ret; 189 int64_t ret;
184 190
185 if (!left->ms.sym && !right->ms.sym) 191 if (!left->ms.sym && !right->ms.sym)
186 return right->level - left->level; 192 return _sort__addr_cmp(left->ip, right->ip);
187 193
188 /* 194 /*
189 * comparing symbol address alone is not enough since it's a 195 * comparing symbol address alone is not enough since it's a
190 * relative address within a dso. 196 * relative address within a dso.
191 */ 197 */
192 ret = sort__dso_cmp(left, right); 198 if (!sort__has_dso) {
193 if (ret != 0) 199 ret = sort__dso_cmp(left, right);
194 return ret; 200 if (ret != 0)
201 return ret;
202 }
195 203
196 return _sort__sym_cmp(left->ms.sym, right->ms.sym); 204 return _sort__sym_cmp(left->ms.sym, right->ms.sym);
197} 205}
@@ -372,7 +380,7 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
372 struct addr_map_symbol *from_r = &right->branch_info->from; 380 struct addr_map_symbol *from_r = &right->branch_info->from;
373 381
374 if (!from_l->sym && !from_r->sym) 382 if (!from_l->sym && !from_r->sym)
375 return right->level - left->level; 383 return _sort__addr_cmp(from_l->addr, from_r->addr);
376 384
377 return _sort__sym_cmp(from_l->sym, from_r->sym); 385 return _sort__sym_cmp(from_l->sym, from_r->sym);
378} 386}
@@ -384,7 +392,7 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
384 struct addr_map_symbol *to_r = &right->branch_info->to; 392 struct addr_map_symbol *to_r = &right->branch_info->to;
385 393
386 if (!to_l->sym && !to_r->sym) 394 if (!to_l->sym && !to_r->sym)
387 return right->level - left->level; 395 return _sort__addr_cmp(to_l->addr, to_r->addr);
388 396
389 return _sort__sym_cmp(to_l->sym, to_r->sym); 397 return _sort__sym_cmp(to_l->sym, to_r->sym);
390} 398}
@@ -1056,6 +1064,8 @@ int sort_dimension__add(const char *tok)
1056 sort__has_parent = 1; 1064 sort__has_parent = 1;
1057 } else if (sd->entry == &sort_sym) { 1065 } else if (sd->entry == &sort_sym) {
1058 sort__has_sym = 1; 1066 sort__has_sym = 1;
1067 } else if (sd->entry == &sort_dso) {
1068 sort__has_dso = 1;
1059 } 1069 }
1060 1070
1061 __sort_dimension__add(sd, i); 1071 __sort_dimension__add(sd, i);
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index 58b2bd8f38c9..7e67879ebd25 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -129,7 +129,7 @@ static struct a2l_data *addr2line_init(const char *path)
129 129
130out: 130out:
131 if (a2l) { 131 if (a2l) {
132 free((void *)a2l->input); 132 zfree((void **)&a2l->input);
133 free(a2l); 133 free(a2l);
134 } 134 }
135 bfd_close(abfd); 135 bfd_close(abfd);
@@ -140,8 +140,8 @@ static void addr2line_cleanup(struct a2l_data *a2l)
140{ 140{
141 if (a2l->abfd) 141 if (a2l->abfd)
142 bfd_close(a2l->abfd); 142 bfd_close(a2l->abfd);
143 free((void *)a2l->input); 143 zfree((void **)&a2l->input);
144 free(a2l->syms); 144 zfree(&a2l->syms);
145 free(a2l); 145 free(a2l);
146} 146}
147 147
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
index cfa906882e2c..4abe23550c73 100644
--- a/tools/perf/util/strbuf.c
+++ b/tools/perf/util/strbuf.c
@@ -28,7 +28,7 @@ void strbuf_init(struct strbuf *sb, ssize_t hint)
28void strbuf_release(struct strbuf *sb) 28void strbuf_release(struct strbuf *sb)
29{ 29{
30 if (sb->alloc) { 30 if (sb->alloc) {
31 free(sb->buf); 31 zfree(&sb->buf);
32 strbuf_init(sb, 0); 32 strbuf_init(sb, 0);
33 } 33 }
34} 34}
diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c
index 3edd0538161f..79a757a2a15c 100644
--- a/tools/perf/util/strfilter.c
+++ b/tools/perf/util/strfilter.c
@@ -14,7 +14,7 @@ static void strfilter_node__delete(struct strfilter_node *node)
14{ 14{
15 if (node) { 15 if (node) {
16 if (node->p && !is_operator(*node->p)) 16 if (node->p && !is_operator(*node->p))
17 free((char *)node->p); 17 zfree((char **)&node->p);
18 strfilter_node__delete(node->l); 18 strfilter_node__delete(node->l);
19 strfilter_node__delete(node->r); 19 strfilter_node__delete(node->r);
20 free(node); 20 free(node);
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index f0b0c008c507..2553e5b55b89 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -128,7 +128,7 @@ void argv_free(char **argv)
128{ 128{
129 char **p; 129 char **p;
130 for (p = argv; *p; p++) 130 for (p = argv; *p; p++)
131 free(*p); 131 zfree(p);
132 132
133 free(argv); 133 free(argv);
134} 134}
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c
index eabdce0a2daa..61a90bf24b4d 100644
--- a/tools/perf/util/strlist.c
+++ b/tools/perf/util/strlist.c
@@ -5,6 +5,7 @@
5 */ 5 */
6 6
7#include "strlist.h" 7#include "strlist.h"
8#include "util.h"
8#include <errno.h> 9#include <errno.h>
9#include <stdio.h> 10#include <stdio.h>
10#include <stdlib.h> 11#include <stdlib.h>
@@ -38,7 +39,7 @@ out_delete:
38static void str_node__delete(struct str_node *snode, bool dupstr) 39static void str_node__delete(struct str_node *snode, bool dupstr)
39{ 40{
40 if (dupstr) 41 if (dupstr)
41 free((void *)snode->s); 42 zfree((void **)&snode->s);
42 free(snode); 43 free(snode);
43} 44}
44 45
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index 56a84f2cc46d..43262b83c541 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -21,6 +21,7 @@
21 21
22#include "perf.h" 22#include "perf.h"
23#include "svghelper.h" 23#include "svghelper.h"
24#include "util.h"
24#include "cpumap.h" 25#include "cpumap.h"
25 26
26static u64 first_time, last_time; 27static u64 first_time, last_time;
@@ -708,8 +709,8 @@ int svg_build_topology_map(char *sib_core, int sib_core_nr,
708 return 0; 709 return 0;
709 710
710exit: 711exit:
711 free(t.sib_core); 712 zfree(&t.sib_core);
712 free(t.sib_thr); 713 zfree(&t.sib_thr);
713 714
714 return -1; 715 return -1;
715} 716}
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index bf0ce29567b6..4b0a127a4d3b 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -554,7 +554,7 @@ bool symsrc__has_symtab(struct symsrc *ss)
554 554
555void symsrc__destroy(struct symsrc *ss) 555void symsrc__destroy(struct symsrc *ss)
556{ 556{
557 free(ss->name); 557 zfree(&ss->name);
558 elf_end(ss->elf); 558 elf_end(ss->elf);
559 close(ss->fd); 559 close(ss->fd);
560} 560}
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index ac7070a2f2b6..bd15f490d04f 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -1,4 +1,5 @@
1#include "symbol.h" 1#include "symbol.h"
2#include "util.h"
2 3
3#include <stdio.h> 4#include <stdio.h>
4#include <fcntl.h> 5#include <fcntl.h>
@@ -275,7 +276,7 @@ bool symsrc__has_symtab(struct symsrc *ss __maybe_unused)
275 276
276void symsrc__destroy(struct symsrc *ss) 277void symsrc__destroy(struct symsrc *ss)
277{ 278{
278 free(ss->name); 279 zfree(&ss->name);
279 close(ss->fd); 280 close(ss->fd);
280} 281}
281 282
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 923d00040bbf..39ce9adbaaf0 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -796,7 +796,7 @@ static void delete_modules(struct rb_root *modules)
796 mi = rb_entry(next, struct module_info, rb_node); 796 mi = rb_entry(next, struct module_info, rb_node);
797 next = rb_next(&mi->rb_node); 797 next = rb_next(&mi->rb_node);
798 rb_erase(&mi->rb_node, modules); 798 rb_erase(&mi->rb_node, modules);
799 free(mi->name); 799 zfree(&mi->name);
800 free(mi); 800 free(mi);
801 } 801 }
802} 802}
@@ -1621,13 +1621,10 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
1621 1621
1622static void vmlinux_path__exit(void) 1622static void vmlinux_path__exit(void)
1623{ 1623{
1624 while (--vmlinux_path__nr_entries >= 0) { 1624 while (--vmlinux_path__nr_entries >= 0)
1625 free(vmlinux_path[vmlinux_path__nr_entries]); 1625 zfree(&vmlinux_path[vmlinux_path__nr_entries]);
1626 vmlinux_path[vmlinux_path__nr_entries] = NULL;
1627 }
1628 1626
1629 free(vmlinux_path); 1627 zfree(&vmlinux_path);
1630 vmlinux_path = NULL;
1631} 1628}
1632 1629
1633static int vmlinux_path__init(void) 1630static int vmlinux_path__init(void)
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 8a9d910c5345..cbd680361806 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -164,6 +164,7 @@ struct mem_info {
164}; 164};
165 165
166struct addr_location { 166struct addr_location {
167 struct machine *machine;
167 struct thread *thread; 168 struct thread *thread;
168 struct map *map; 169 struct map *map;
169 struct symbol *sym; 170 struct symbol *sym;
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 9b5f856cc280..5d3215912105 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -9,6 +9,7 @@
9#include "strlist.h" 9#include "strlist.h"
10#include <string.h> 10#include <string.h>
11#include "thread_map.h" 11#include "thread_map.h"
12#include "util.h"
12 13
13/* Skip "." and ".." directories */ 14/* Skip "." and ".." directories */
14static int filter(const struct dirent *dir) 15static int filter(const struct dirent *dir)
@@ -40,7 +41,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
40 } 41 }
41 42
42 for (i=0; i<items; i++) 43 for (i=0; i<items; i++)
43 free(namelist[i]); 44 zfree(&namelist[i]);
44 free(namelist); 45 free(namelist);
45 46
46 return threads; 47 return threads;
@@ -117,7 +118,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
117 threads->map[threads->nr + i] = atoi(namelist[i]->d_name); 118 threads->map[threads->nr + i] = atoi(namelist[i]->d_name);
118 119
119 for (i = 0; i < items; i++) 120 for (i = 0; i < items; i++)
120 free(namelist[i]); 121 zfree(&namelist[i]);
121 free(namelist); 122 free(namelist);
122 123
123 threads->nr += items; 124 threads->nr += items;
@@ -134,12 +135,11 @@ out_free_threads:
134 135
135out_free_namelist: 136out_free_namelist:
136 for (i = 0; i < items; i++) 137 for (i = 0; i < items; i++)
137 free(namelist[i]); 138 zfree(&namelist[i]);
138 free(namelist); 139 free(namelist);
139 140
140out_free_closedir: 141out_free_closedir:
141 free(threads); 142 zfree(&threads);
142 threads = NULL;
143 goto out_closedir; 143 goto out_closedir;
144} 144}
145 145
@@ -194,7 +194,7 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
194 194
195 for (i = 0; i < items; i++) { 195 for (i = 0; i < items; i++) {
196 threads->map[j++] = atoi(namelist[i]->d_name); 196 threads->map[j++] = atoi(namelist[i]->d_name);
197 free(namelist[i]); 197 zfree(&namelist[i]);
198 } 198 }
199 threads->nr = total_tasks; 199 threads->nr = total_tasks;
200 free(namelist); 200 free(namelist);
@@ -206,12 +206,11 @@ out:
206 206
207out_free_namelist: 207out_free_namelist:
208 for (i = 0; i < items; i++) 208 for (i = 0; i < items; i++)
209 free(namelist[i]); 209 zfree(&namelist[i]);
210 free(namelist); 210 free(namelist);
211 211
212out_free_threads: 212out_free_threads:
213 free(threads); 213 zfree(&threads);
214 threads = NULL;
215 goto out; 214 goto out;
216} 215}
217 216
@@ -262,8 +261,7 @@ out:
262 return threads; 261 return threads;
263 262
264out_free_threads: 263out_free_threads:
265 free(threads); 264 zfree(&threads);
266 threads = NULL;
267 goto out; 265 goto out;
268} 266}
269 267
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index ce793c7dd23c..8e517def925b 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -26,7 +26,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
26 float samples_per_sec; 26 float samples_per_sec;
27 float ksamples_per_sec; 27 float ksamples_per_sec;
28 float esamples_percent; 28 float esamples_percent;
29 struct perf_record_opts *opts = &top->record_opts; 29 struct record_opts *opts = &top->record_opts;
30 struct target *target = &opts->target; 30 struct target *target = &opts->target;
31 size_t ret = 0; 31 size_t ret = 0;
32 32
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index 88cfeaff600b..dab14d0ad3d0 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -14,7 +14,7 @@ struct perf_session;
14struct perf_top { 14struct perf_top {
15 struct perf_tool tool; 15 struct perf_tool tool;
16 struct perf_evlist *evlist; 16 struct perf_evlist *evlist;
17 struct perf_record_opts record_opts; 17 struct record_opts record_opts;
18 /* 18 /*
19 * Symbols will be added here in perf_event__process_sample and will 19 * Symbols will be added here in perf_event__process_sample and will
20 * get out after decayed. 20 * get out after decayed.
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index c354b95a2348..7e6fcfe8b438 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -397,8 +397,8 @@ put_tracepoints_path(struct tracepoint_path *tps)
397 struct tracepoint_path *t = tps; 397 struct tracepoint_path *t = tps;
398 398
399 tps = tps->next; 399 tps = tps->next;
400 free(t->name); 400 zfree(&t->name);
401 free(t->system); 401 zfree(&t->system);
402 free(t); 402 free(t);
403 } 403 }
404} 404}
@@ -562,10 +562,8 @@ out:
562 output_fd = fd; 562 output_fd = fd;
563 } 563 }
564 564
565 if (err) { 565 if (err)
566 free(tdata); 566 zfree(&tdata);
567 tdata = NULL;
568 }
569 567
570 put_tracepoints_path(tps); 568 put_tracepoints_path(tps);
571 return tdata; 569 return tdata;
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
index 95199e4eea97..57aaccc1692e 100644
--- a/tools/perf/util/trace-event-scripting.c
+++ b/tools/perf/util/trace-event-scripting.c
@@ -38,9 +38,8 @@ static int stop_script_unsupported(void)
38static void process_event_unsupported(union perf_event *event __maybe_unused, 38static void process_event_unsupported(union perf_event *event __maybe_unused,
39 struct perf_sample *sample __maybe_unused, 39 struct perf_sample *sample __maybe_unused,
40 struct perf_evsel *evsel __maybe_unused, 40 struct perf_evsel *evsel __maybe_unused,
41 struct machine *machine __maybe_unused,
42 struct thread *thread __maybe_unused, 41 struct thread *thread __maybe_unused,
43 struct addr_location *al __maybe_unused) 42 struct addr_location *al __maybe_unused)
44{ 43{
45} 44}
46 45
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 3a01618c5b87..7b6d68688327 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -68,7 +68,6 @@ struct scripting_ops {
68 void (*process_event) (union perf_event *event, 68 void (*process_event) (union perf_event *event,
69 struct perf_sample *sample, 69 struct perf_sample *sample,
70 struct perf_evsel *evsel, 70 struct perf_evsel *evsel,
71 struct machine *machine,
72 struct thread *thread, 71 struct thread *thread,
73 struct addr_location *al); 72 struct addr_location *al);
74 int (*generate_script) (struct pevent *pevent, const char *outfile); 73 int (*generate_script) (struct pevent *pevent, const char *outfile);
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 9a2c268ad718..6995d66f225c 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -186,6 +186,8 @@ static inline void *zalloc(size_t size)
186 return calloc(1, size); 186 return calloc(1, size);
187} 187}
188 188
189#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
190
189static inline int has_extension(const char *filename, const char *ext) 191static inline int has_extension(const char *filename, const char *ext)
190{ 192{
191 size_t len = strlen(filename); 193 size_t len = strlen(filename);
diff --git a/tools/perf/util/values.c b/tools/perf/util/values.c
index 697c8b4e59cc..0fb3c1fcd3e6 100644
--- a/tools/perf/util/values.c
+++ b/tools/perf/util/values.c
@@ -31,14 +31,14 @@ void perf_read_values_destroy(struct perf_read_values *values)
31 return; 31 return;
32 32
33 for (i = 0; i < values->threads; i++) 33 for (i = 0; i < values->threads; i++)
34 free(values->value[i]); 34 zfree(&values->value[i]);
35 free(values->value); 35 zfree(&values->value);
36 free(values->pid); 36 zfree(&values->pid);
37 free(values->tid); 37 zfree(&values->tid);
38 free(values->counterrawid); 38 zfree(&values->counterrawid);
39 for (i = 0; i < values->counters; i++) 39 for (i = 0; i < values->counters; i++)
40 free(values->countername[i]); 40 zfree(&values->countername[i]);
41 free(values->countername); 41 zfree(&values->countername);
42} 42}
43 43
44static void perf_read_values__enlarge_threads(struct perf_read_values *values) 44static void perf_read_values__enlarge_threads(struct perf_read_values *values)