aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2017-06-20 04:49:08 -0400
committerIngo Molnar <mingo@kernel.org>2017-06-20 04:49:08 -0400
commit007b811b4041989ec2dc91b9614aa2c41332723e (patch)
tree34ba98f00635fea2d0f3087e8859afe7b83e74d0 /tools/perf
parent2eb0fc9bfe7485fec16030b85ff586e7aaea2b6f (diff)
parentdfe1c6d7efa8ead6878b73216d4c891a28207528 (diff)
Merge tag 'perf-core-for-mingo-4.13-20170719' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Allow adding and removing fields to the default 'perf script' columns, using + or - as field prefixes to do so (Andi Kleen) - Display titles in left frame in the annotate browser (Jin Yao) - Allow resolving the DSO name with 'perf script -F brstack{sym,off},dso' (Mark Santaniello) - Support function filtering in 'perf ftrace' (Namhyung Kim) - Allow specifying function call depth in 'perf ftrace' (Namhyumg Kim) Infrastructure changes: - Adopt __noreturn, __printf, __scanf, noinline, __packed and __aligned __alignment__(()) markers, to make the tools/ source code base to be more compact and look more like kernel code (Arnaldo Carvalho de Melo) - Remove unnecessary check in annotate_browser_write() (Jin Yao) - Return arch from symbol__disassemble() so that callers, such as the annotate TUI browser to use arch specific formattings, such as the upcoming instruction micro-op fusion on Intel Core (Jin Yao) - Remove superfluous check before use in the coresight code base (Kim Phillips) - Remove unused SAMPLE_SIZE defines and BTS priv array (Kim Phillips) - Error handling fix/tidy ups in 'perf config' (Taeung Song) - Avoid error in the BPF proggie built with clang in 'perf test llvm' when PROFILE_ALL_BRANCHES is set (Wang Nan) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-ftrace.txt33
-rw-r--r--tools/perf/Documentation/perf-script.txt12
-rw-r--r--tools/perf/arch/arm/util/cs-etm.c29
-rw-r--r--tools/perf/arch/x86/util/intel-bts.c4
-rw-r--r--tools/perf/arch/x86/util/intel-pt.c4
-rw-r--r--tools/perf/bench/numa.c2
-rw-r--r--tools/perf/builtin-config.c67
-rw-r--r--tools/perf/builtin-ftrace.c159
-rw-r--r--tools/perf/builtin-script.c146
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/jvmti/jvmti_agent.h2
-rw-r--r--tools/perf/jvmti/libjvmti.c5
-rw-r--r--tools/perf/pmu-events/jevents.c4
-rw-r--r--tools/perf/tests/bp_signal.c3
-rw-r--r--tools/perf/tests/bp_signal_overflow.c3
-rw-r--r--tools/perf/tests/bpf-script-test-prologue.c9
-rw-r--r--tools/perf/tests/dwarf-unwind.c15
-rw-r--r--tools/perf/ui/browsers/annotate.c54
-rw-r--r--tools/perf/ui/gtk/annotate.c3
-rw-r--r--tools/perf/util/annotate.c10
-rw-r--r--tools/perf/util/annotate.h4
-rw-r--r--tools/perf/util/cache.h3
-rw-r--r--tools/perf/util/debug.h11
-rw-r--r--tools/perf/util/evlist.h3
-rw-r--r--tools/perf/util/evsel.c3
-rw-r--r--tools/perf/util/genelf_debug.c5
-rw-r--r--tools/perf/util/header.c3
-rw-r--r--tools/perf/util/intel-bts.c2
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-log.h4
-rw-r--r--tools/perf/util/pmu.h4
-rw-r--r--tools/perf/util/probe-event.h4
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c3
-rw-r--r--tools/perf/util/strbuf.h4
-rw-r--r--tools/perf/util/usage.c6
-rw-r--r--tools/perf/util/util.h18
35 files changed, 482 insertions, 161 deletions
diff --git a/tools/perf/Documentation/perf-ftrace.txt b/tools/perf/Documentation/perf-ftrace.txt
index 6e6a8b22c859..721a447f046e 100644
--- a/tools/perf/Documentation/perf-ftrace.txt
+++ b/tools/perf/Documentation/perf-ftrace.txt
@@ -48,6 +48,39 @@ OPTIONS
48 Ranges of CPUs are specified with -: 0-2. 48 Ranges of CPUs are specified with -: 0-2.
49 Default is to trace on all online CPUs. 49 Default is to trace on all online CPUs.
50 50
51-T::
52--trace-funcs=::
53 Only trace functions given by the argument. Multiple functions
54 can be given by using this option more than once. The function
55 argument also can be a glob pattern. It will be passed to
56 'set_ftrace_filter' in tracefs.
57
58-N::
59--notrace-funcs=::
60 Do not trace functions given by the argument. Like -T option,
61 this can be used more than once to specify multiple functions
62 (or glob patterns). It will be passed to 'set_ftrace_notrace'
63 in tracefs.
64
65-G::
66--graph-funcs=::
67 Set graph filter on the given function (or a glob pattern).
68 This is useful for the function_graph tracer only and enables
69 tracing for functions executed from the given function.
70 This can be used more than once to specify multiple functions.
71 It will be passed to 'set_graph_function' in tracefs.
72
73-g::
74--nograph-funcs=::
75 Set graph notrace filter on the given function (or a glob pattern).
76 Like -G option, this is useful for the function_graph tracer only
77 and disables tracing for function executed from the given function.
78 This can be used more than once to specify multiple functions.
79 It will be passed to 'set_graph_notrace' in tracefs.
80
81-D::
82--graph-depth=::
83 Set max depth for function graph tracer to follow
51 84
52SEE ALSO 85SEE ALSO
53-------- 86--------
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 3517e204a2b3..e2468ed6a307 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -116,7 +116,7 @@ OPTIONS
116--fields:: 116--fields::
117 Comma separated list of fields to print. Options are: 117 Comma separated list of fields to print. Options are:
118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, 118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff,
119 srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, 119 srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, brstackoff,
120 callindent, insn, insnlen. Field list can be prepended with the type, trace, sw or hw, 120 callindent, insn, insnlen. Field list can be prepended with the type, trace, sw or hw,
121 to indicate to which event type the field list applies. 121 to indicate to which event type the field list applies.
122 e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace 122 e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
@@ -130,6 +130,14 @@ OPTIONS
130 i.e., the specified fields apply to all event types if the type string 130 i.e., the specified fields apply to all event types if the type string
131 is not given. 131 is not given.
132 132
133 In addition to overriding fields, it is also possible to add or remove
134 fields from the defaults. For example
135
136 -F -cpu,+insn
137
138 removes the cpu field and adds the insn field. Adding/removing fields
139 cannot be mixed with normal overriding.
140
133 The arguments are processed in the order received. A later usage can 141 The arguments are processed in the order received. A later usage can
134 reset a prior request. e.g.: 142 reset a prior request. e.g.:
135 143
@@ -203,6 +211,8 @@ OPTIONS
203 is printed. This is the full execution path leading to the sample. This is only supported when the 211 is printed. This is the full execution path leading to the sample. This is only supported when the
204 sample was recorded with perf record -b or -j any. 212 sample was recorded with perf record -b or -j any.
205 213
214 The brstackoff field will print an offset into a specific dso/binary.
215
206-k:: 216-k::
207--vmlinux=<file>:: 217--vmlinux=<file>::
208 vmlinux pathname 218 vmlinux pathname
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index 29361d9b635a..7ce3d1a25133 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -17,6 +17,7 @@
17 17
18#include <api/fs/fs.h> 18#include <api/fs/fs.h>
19#include <linux/bitops.h> 19#include <linux/bitops.h>
20#include <linux/compiler.h>
20#include <linux/coresight-pmu.h> 21#include <linux/coresight-pmu.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
22#include <linux/log2.h> 23#include <linux/log2.h>
@@ -202,19 +203,18 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
202 pr_debug2("%s snapshot size: %zu\n", CORESIGHT_ETM_PMU_NAME, 203 pr_debug2("%s snapshot size: %zu\n", CORESIGHT_ETM_PMU_NAME,
203 opts->auxtrace_snapshot_size); 204 opts->auxtrace_snapshot_size);
204 205
205 if (cs_etm_evsel) { 206 /*
206 /* 207 * To obtain the auxtrace buffer file descriptor, the auxtrace
207 * To obtain the auxtrace buffer file descriptor, the auxtrace 208 * event must come first.
208 * event must come first. 209 */
209 */ 210 perf_evlist__to_front(evlist, cs_etm_evsel);
210 perf_evlist__to_front(evlist, cs_etm_evsel); 211
211 /* 212 /*
212 * In the case of per-cpu mmaps, we need the CPU on the 213 * In the case of per-cpu mmaps, we need the CPU on the
213 * AUX event. 214 * AUX event.
214 */ 215 */
215 if (!cpu_map__empty(cpus)) 216 if (!cpu_map__empty(cpus))
216 perf_evsel__set_sample_bit(cs_etm_evsel, CPU); 217 perf_evsel__set_sample_bit(cs_etm_evsel, CPU);
217 }
218 218
219 /* Add dummy event to keep tracking */ 219 /* Add dummy event to keep tracking */
220 if (opts->full_auxtrace) { 220 if (opts->full_auxtrace) {
@@ -583,8 +583,7 @@ static FILE *cs_device__open_file(const char *name)
583 583
584} 584}
585 585
586static __attribute__((format(printf, 2, 3))) 586static int __printf(2, 3) cs_device__print_file(const char *name, const char *fmt, ...)
587int cs_device__print_file(const char *name, const char *fmt, ...)
588{ 587{
589 va_list args; 588 va_list args;
590 FILE *file; 589 FILE *file;
diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c
index af2bce7a2cd6..781df40b2966 100644
--- a/tools/perf/arch/x86/util/intel-bts.c
+++ b/tools/perf/arch/x86/util/intel-bts.c
@@ -35,10 +35,6 @@
35#define KiB_MASK(x) (KiB(x) - 1) 35#define KiB_MASK(x) (KiB(x) - 1)
36#define MiB_MASK(x) (MiB(x) - 1) 36#define MiB_MASK(x) (MiB(x) - 1)
37 37
38#define INTEL_BTS_DFLT_SAMPLE_SIZE KiB(4)
39
40#define INTEL_BTS_MAX_SAMPLE_SIZE KiB(60)
41
42struct intel_bts_snapshot_ref { 38struct intel_bts_snapshot_ref {
43 void *ref_buf; 39 void *ref_buf;
44 size_t ref_offset; 40 size_t ref_offset;
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index f630de0206a1..6fe667b3269e 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -40,10 +40,6 @@
40#define KiB_MASK(x) (KiB(x) - 1) 40#define KiB_MASK(x) (KiB(x) - 1)
41#define MiB_MASK(x) (MiB(x) - 1) 41#define MiB_MASK(x) (MiB(x) - 1)
42 42
43#define INTEL_PT_DEFAULT_SAMPLE_SIZE KiB(4)
44
45#define INTEL_PT_MAX_SAMPLE_SIZE KiB(60)
46
47#define INTEL_PT_PSB_PERIOD_NEAR 256 43#define INTEL_PT_PSB_PERIOD_NEAR 256
48 44
49struct intel_pt_snapshot_ref { 45struct intel_pt_snapshot_ref {
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 27de0c8c5c19..469d65b21122 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -700,7 +700,7 @@ static inline uint32_t lfsr_32(uint32_t lfsr)
700 * kernel (KSM, zero page, etc.) cannot optimize away RAM 700 * kernel (KSM, zero page, etc.) cannot optimize away RAM
701 * accesses: 701 * accesses:
702 */ 702 */
703static inline u64 access_data(u64 *data __attribute__((unused)), u64 val) 703static inline u64 access_data(u64 *data, u64 val)
704{ 704{
705 if (g->p.data_reads) 705 if (g->p.data_reads)
706 val += *data; 706 val += *data;
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 80668fa7556e..ece45582a48d 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -156,7 +156,7 @@ static int parse_config_arg(char *arg, char **var, char **value)
156 156
157int cmd_config(int argc, const char **argv) 157int cmd_config(int argc, const char **argv)
158{ 158{
159 int i, ret = 0; 159 int i, ret = -1;
160 struct perf_config_set *set; 160 struct perf_config_set *set;
161 char *user_config = mkpath("%s/.perfconfig", getenv("HOME")); 161 char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));
162 const char *config_filename; 162 const char *config_filename;
@@ -186,10 +186,8 @@ int cmd_config(int argc, const char **argv)
186 * because of reinitializing with options config file location. 186 * because of reinitializing with options config file location.
187 */ 187 */
188 set = perf_config_set__new(); 188 set = perf_config_set__new();
189 if (!set) { 189 if (!set)
190 ret = -1;
191 goto out_err; 190 goto out_err;
192 }
193 191
194 switch (actions) { 192 switch (actions) {
195 case ACTION_LIST: 193 case ACTION_LIST:
@@ -197,41 +195,54 @@ int cmd_config(int argc, const char **argv)
197 pr_err("Error: takes no arguments\n"); 195 pr_err("Error: takes no arguments\n");
198 parse_options_usage(config_usage, config_options, "l", 1); 196 parse_options_usage(config_usage, config_options, "l", 1);
199 } else { 197 } else {
200 ret = show_config(set); 198 if (show_config(set) < 0) {
201 if (ret < 0)
202 pr_err("Nothing configured, " 199 pr_err("Nothing configured, "
203 "please check your %s \n", config_filename); 200 "please check your %s \n", config_filename);
201 goto out_err;
202 }
204 } 203 }
205 break; 204 break;
206 default: 205 default:
207 if (argc) { 206 if (!argc) {
208 for (i = 0; argv[i]; i++) { 207 usage_with_options(config_usage, config_options);
209 char *var, *value; 208 break;
210 char *arg = strdup(argv[i]); 209 }
211
212 if (!arg) {
213 pr_err("%s: strdup failed\n", __func__);
214 ret = -1;
215 break;
216 }
217 210
218 if (parse_config_arg(arg, &var, &value) < 0) { 211 for (i = 0; argv[i]; i++) {
219 free(arg); 212 char *var, *value;
220 ret = -1; 213 char *arg = strdup(argv[i]);
221 break; 214
222 } 215 if (!arg) {
216 pr_err("%s: strdup failed\n", __func__);
217 goto out_err;
218 }
223 219
224 if (value == NULL) 220 if (parse_config_arg(arg, &var, &value) < 0) {
225 ret = show_spec_config(set, var);
226 else
227 ret = set_config(set, config_filename, var, value);
228 free(arg); 221 free(arg);
222 goto out_err;
229 } 223 }
230 } else 224
231 usage_with_options(config_usage, config_options); 225 if (value == NULL) {
226 if (show_spec_config(set, var) < 0) {
227 pr_err("%s is not configured: %s\n",
228 var, config_filename);
229 free(arg);
230 goto out_err;
231 }
232 } else {
233 if (set_config(set, config_filename, var, value) < 0) {
234 pr_err("Failed to set '%s=%s' on %s\n",
235 var, value, config_filename);
236 free(arg);
237 goto out_err;
238 }
239 }
240 free(arg);
241 }
232 } 242 }
233 243
234 perf_config_set__delete(set); 244 ret = 0;
235out_err: 245out_err:
246 perf_config_set__delete(set);
236 return ret; 247 return ret;
237} 248}
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
index 9e0b35cd0eea..dd26c62c9893 100644
--- a/tools/perf/builtin-ftrace.c
+++ b/tools/perf/builtin-ftrace.c
@@ -28,9 +28,19 @@
28#define DEFAULT_TRACER "function_graph" 28#define DEFAULT_TRACER "function_graph"
29 29
30struct perf_ftrace { 30struct perf_ftrace {
31 struct perf_evlist *evlist; 31 struct perf_evlist *evlist;
32 struct target target; 32 struct target target;
33 const char *tracer; 33 const char *tracer;
34 struct list_head filters;
35 struct list_head notrace;
36 struct list_head graph_funcs;
37 struct list_head nograph_funcs;
38 int graph_depth;
39};
40
41struct filter_entry {
42 struct list_head list;
43 char name[];
34}; 44};
35 45
36static bool done; 46static bool done;
@@ -61,6 +71,7 @@ static int __write_tracing_file(const char *name, const char *val, bool append)
61 int fd, ret = -1; 71 int fd, ret = -1;
62 ssize_t size = strlen(val); 72 ssize_t size = strlen(val);
63 int flags = O_WRONLY; 73 int flags = O_WRONLY;
74 char errbuf[512];
64 75
65 file = get_tracing_file(name); 76 file = get_tracing_file(name);
66 if (!file) { 77 if (!file) {
@@ -75,14 +86,16 @@ static int __write_tracing_file(const char *name, const char *val, bool append)
75 86
76 fd = open(file, flags); 87 fd = open(file, flags);
77 if (fd < 0) { 88 if (fd < 0) {
78 pr_debug("cannot open tracing file: %s\n", name); 89 pr_debug("cannot open tracing file: %s: %s\n",
90 name, str_error_r(errno, errbuf, sizeof(errbuf)));
79 goto out; 91 goto out;
80 } 92 }
81 93
82 if (write(fd, val, size) == size) 94 if (write(fd, val, size) == size)
83 ret = 0; 95 ret = 0;
84 else 96 else
85 pr_debug("write '%s' to tracing/%s failed\n", val, name); 97 pr_debug("write '%s' to tracing/%s failed: %s\n",
98 val, name, str_error_r(errno, errbuf, sizeof(errbuf)));
86 99
87 close(fd); 100 close(fd);
88out: 101out:
@@ -101,6 +114,7 @@ static int append_tracing_file(const char *name, const char *val)
101} 114}
102 115
103static int reset_tracing_cpu(void); 116static int reset_tracing_cpu(void);
117static void reset_tracing_filters(void);
104 118
105static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused) 119static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
106{ 120{
@@ -116,6 +130,10 @@ static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
116 if (reset_tracing_cpu() < 0) 130 if (reset_tracing_cpu() < 0)
117 return -1; 131 return -1;
118 132
133 if (write_tracing_file("max_graph_depth", "0") < 0)
134 return -1;
135
136 reset_tracing_filters();
119 return 0; 137 return 0;
120} 138}
121 139
@@ -181,6 +199,68 @@ static int reset_tracing_cpu(void)
181 return ret; 199 return ret;
182} 200}
183 201
202static int __set_tracing_filter(const char *filter_file, struct list_head *funcs)
203{
204 struct filter_entry *pos;
205
206 list_for_each_entry(pos, funcs, list) {
207 if (append_tracing_file(filter_file, pos->name) < 0)
208 return -1;
209 }
210
211 return 0;
212}
213
214static int set_tracing_filters(struct perf_ftrace *ftrace)
215{
216 int ret;
217
218 ret = __set_tracing_filter("set_ftrace_filter", &ftrace->filters);
219 if (ret < 0)
220 return ret;
221
222 ret = __set_tracing_filter("set_ftrace_notrace", &ftrace->notrace);
223 if (ret < 0)
224 return ret;
225
226 ret = __set_tracing_filter("set_graph_function", &ftrace->graph_funcs);
227 if (ret < 0)
228 return ret;
229
230 /* old kernels do not have this filter */
231 __set_tracing_filter("set_graph_notrace", &ftrace->nograph_funcs);
232
233 return ret;
234}
235
236static void reset_tracing_filters(void)
237{
238 write_tracing_file("set_ftrace_filter", " ");
239 write_tracing_file("set_ftrace_notrace", " ");
240 write_tracing_file("set_graph_function", " ");
241 write_tracing_file("set_graph_notrace", " ");
242}
243
244static int set_tracing_depth(struct perf_ftrace *ftrace)
245{
246 char buf[16];
247
248 if (ftrace->graph_depth == 0)
249 return 0;
250
251 if (ftrace->graph_depth < 0) {
252 pr_err("invalid graph depth: %d\n", ftrace->graph_depth);
253 return -1;
254 }
255
256 snprintf(buf, sizeof(buf), "%d", ftrace->graph_depth);
257
258 if (write_tracing_file("max_graph_depth", buf) < 0)
259 return -1;
260
261 return 0;
262}
263
184static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) 264static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
185{ 265{
186 char *trace_file; 266 char *trace_file;
@@ -223,11 +303,23 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
223 goto out_reset; 303 goto out_reset;
224 } 304 }
225 305
306 if (set_tracing_filters(ftrace) < 0) {
307 pr_err("failed to set tracing filters\n");
308 goto out_reset;
309 }
310
311 if (set_tracing_depth(ftrace) < 0) {
312 pr_err("failed to set graph depth\n");
313 goto out_reset;
314 }
315
226 if (write_tracing_file("current_tracer", ftrace->tracer) < 0) { 316 if (write_tracing_file("current_tracer", ftrace->tracer) < 0) {
227 pr_err("failed to set current_tracer to %s\n", ftrace->tracer); 317 pr_err("failed to set current_tracer to %s\n", ftrace->tracer);
228 goto out_reset; 318 goto out_reset;
229 } 319 }
230 320
321 setup_pager();
322
231 trace_file = get_tracing_file("trace_pipe"); 323 trace_file = get_tracing_file("trace_pipe");
232 if (!trace_file) { 324 if (!trace_file) {
233 pr_err("failed to open trace_pipe\n"); 325 pr_err("failed to open trace_pipe\n");
@@ -251,8 +343,6 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
251 goto out_close_fd; 343 goto out_close_fd;
252 } 344 }
253 345
254 setup_pager();
255
256 perf_evlist__start_workload(ftrace->evlist); 346 perf_evlist__start_workload(ftrace->evlist);
257 347
258 while (!done) { 348 while (!done) {
@@ -307,6 +397,32 @@ static int perf_ftrace_config(const char *var, const char *value, void *cb)
307 return -1; 397 return -1;
308} 398}
309 399
400static int parse_filter_func(const struct option *opt, const char *str,
401 int unset __maybe_unused)
402{
403 struct list_head *head = opt->value;
404 struct filter_entry *entry;
405
406 entry = malloc(sizeof(*entry) + strlen(str) + 1);
407 if (entry == NULL)
408 return -ENOMEM;
409
410 strcpy(entry->name, str);
411 list_add_tail(&entry->list, head);
412
413 return 0;
414}
415
416static void delete_filter_func(struct list_head *head)
417{
418 struct filter_entry *pos, *tmp;
419
420 list_for_each_entry_safe(pos, tmp, head, list) {
421 list_del(&pos->list);
422 free(pos);
423 }
424}
425
310int cmd_ftrace(int argc, const char **argv) 426int cmd_ftrace(int argc, const char **argv)
311{ 427{
312 int ret; 428 int ret;
@@ -330,9 +446,24 @@ int cmd_ftrace(int argc, const char **argv)
330 "system-wide collection from all CPUs"), 446 "system-wide collection from all CPUs"),
331 OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu", 447 OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu",
332 "list of cpus to monitor"), 448 "list of cpus to monitor"),
449 OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func",
450 "trace given functions only", parse_filter_func),
451 OPT_CALLBACK('N', "notrace-funcs", &ftrace.notrace, "func",
452 "do not trace given functions", parse_filter_func),
453 OPT_CALLBACK('G', "graph-funcs", &ftrace.graph_funcs, "func",
454 "Set graph filter on given functions", parse_filter_func),
455 OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func",
456 "Set nograph filter on given functions", parse_filter_func),
457 OPT_INTEGER('D', "graph-depth", &ftrace.graph_depth,
458 "Max depth for function graph tracer"),
333 OPT_END() 459 OPT_END()
334 }; 460 };
335 461
462 INIT_LIST_HEAD(&ftrace.filters);
463 INIT_LIST_HEAD(&ftrace.notrace);
464 INIT_LIST_HEAD(&ftrace.graph_funcs);
465 INIT_LIST_HEAD(&ftrace.nograph_funcs);
466
336 ret = perf_config(perf_ftrace_config, &ftrace); 467 ret = perf_config(perf_ftrace_config, &ftrace);
337 if (ret < 0) 468 if (ret < 0)
338 return -1; 469 return -1;
@@ -348,12 +479,14 @@ int cmd_ftrace(int argc, const char **argv)
348 479
349 target__strerror(&ftrace.target, ret, errbuf, 512); 480 target__strerror(&ftrace.target, ret, errbuf, 512);
350 pr_err("%s\n", errbuf); 481 pr_err("%s\n", errbuf);
351 return -EINVAL; 482 goto out_delete_filters;
352 } 483 }
353 484
354 ftrace.evlist = perf_evlist__new(); 485 ftrace.evlist = perf_evlist__new();
355 if (ftrace.evlist == NULL) 486 if (ftrace.evlist == NULL) {
356 return -ENOMEM; 487 ret = -ENOMEM;
488 goto out_delete_filters;
489 }
357 490
358 ret = perf_evlist__create_maps(ftrace.evlist, &ftrace.target); 491 ret = perf_evlist__create_maps(ftrace.evlist, &ftrace.target);
359 if (ret < 0) 492 if (ret < 0)
@@ -364,5 +497,11 @@ int cmd_ftrace(int argc, const char **argv)
364out_delete_evlist: 497out_delete_evlist:
365 perf_evlist__delete(ftrace.evlist); 498 perf_evlist__delete(ftrace.evlist);
366 499
500out_delete_filters:
501 delete_filter_func(&ftrace.filters);
502 delete_filter_func(&ftrace.notrace);
503 delete_filter_func(&ftrace.graph_funcs);
504 delete_filter_func(&ftrace.nograph_funcs);
505
367 return ret; 506 return ret;
368} 507}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 4761b0d7fcb5..db5261c3f719 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -85,6 +85,7 @@ enum perf_output_field {
85 PERF_OUTPUT_INSN = 1U << 21, 85 PERF_OUTPUT_INSN = 1U << 21,
86 PERF_OUTPUT_INSNLEN = 1U << 22, 86 PERF_OUTPUT_INSNLEN = 1U << 22,
87 PERF_OUTPUT_BRSTACKINSN = 1U << 23, 87 PERF_OUTPUT_BRSTACKINSN = 1U << 23,
88 PERF_OUTPUT_BRSTACKOFF = 1U << 24,
88}; 89};
89 90
90struct output_option { 91struct output_option {
@@ -115,6 +116,7 @@ struct output_option {
115 {.str = "insn", .field = PERF_OUTPUT_INSN}, 116 {.str = "insn", .field = PERF_OUTPUT_INSN},
116 {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN}, 117 {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
117 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN}, 118 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
119 {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
118}; 120};
119 121
120/* default set to maintain compatibility with current format */ 122/* default set to maintain compatibility with current format */
@@ -298,10 +300,10 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
298 "selected.\n"); 300 "selected.\n");
299 return -EINVAL; 301 return -EINVAL;
300 } 302 }
301 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 303 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR) &&
302 pr_err("Display of DSO requested but neither sample IP nor " 304 !PRINT_FIELD(BRSTACK) && !PRINT_FIELD(BRSTACKSYM) && !PRINT_FIELD(BRSTACKOFF)) {
303 "sample address\nis selected. Hence, no addresses to convert " 305 pr_err("Display of DSO requested but no address to convert. Select\n"
304 "to DSO.\n"); 306 "sample IP, sample address, brstack, brstacksym, or brstackoff.\n");
305 return -EINVAL; 307 return -EINVAL;
306 } 308 }
307 if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) { 309 if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) {
@@ -514,18 +516,43 @@ mispred_str(struct branch_entry *br)
514 return br->flags.predicted ? 'P' : 'M'; 516 return br->flags.predicted ? 'P' : 'M';
515} 517}
516 518
517static void print_sample_brstack(struct perf_sample *sample) 519static void print_sample_brstack(struct perf_sample *sample,
520 struct thread *thread,
521 struct perf_event_attr *attr)
518{ 522{
519 struct branch_stack *br = sample->branch_stack; 523 struct branch_stack *br = sample->branch_stack;
520 u64 i; 524 struct addr_location alf, alt;
525 u64 i, from, to;
521 526
522 if (!(br && br->nr)) 527 if (!(br && br->nr))
523 return; 528 return;
524 529
525 for (i = 0; i < br->nr; i++) { 530 for (i = 0; i < br->nr; i++) {
526 printf(" 0x%"PRIx64"/0x%"PRIx64"/%c/%c/%c/%d ", 531 from = br->entries[i].from;
527 br->entries[i].from, 532 to = br->entries[i].to;
528 br->entries[i].to, 533
534 if (PRINT_FIELD(DSO)) {
535 memset(&alf, 0, sizeof(alf));
536 memset(&alt, 0, sizeof(alt));
537 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf);
538 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
539 }
540
541 printf("0x%"PRIx64, from);
542 if (PRINT_FIELD(DSO)) {
543 printf("(");
544 map__fprintf_dsoname(alf.map, stdout);
545 printf(")");
546 }
547
548 printf("/0x%"PRIx64, to);
549 if (PRINT_FIELD(DSO)) {
550 printf("(");
551 map__fprintf_dsoname(alt.map, stdout);
552 printf(")");
553 }
554
555 printf("/%c/%c/%c/%d ",
529 mispred_str( br->entries + i), 556 mispred_str( br->entries + i),
530 br->entries[i].flags.in_tx? 'X' : '-', 557 br->entries[i].flags.in_tx? 'X' : '-',
531 br->entries[i].flags.abort? 'A' : '-', 558 br->entries[i].flags.abort? 'A' : '-',
@@ -534,7 +561,8 @@ static void print_sample_brstack(struct perf_sample *sample)
534} 561}
535 562
536static void print_sample_brstacksym(struct perf_sample *sample, 563static void print_sample_brstacksym(struct perf_sample *sample,
537 struct thread *thread) 564 struct thread *thread,
565 struct perf_event_attr *attr)
538{ 566{
539 struct branch_stack *br = sample->branch_stack; 567 struct branch_stack *br = sample->branch_stack;
540 struct addr_location alf, alt; 568 struct addr_location alf, alt;
@@ -559,8 +587,18 @@ static void print_sample_brstacksym(struct perf_sample *sample,
559 alt.sym = map__find_symbol(alt.map, alt.addr); 587 alt.sym = map__find_symbol(alt.map, alt.addr);
560 588
561 symbol__fprintf_symname_offs(alf.sym, &alf, stdout); 589 symbol__fprintf_symname_offs(alf.sym, &alf, stdout);
590 if (PRINT_FIELD(DSO)) {
591 printf("(");
592 map__fprintf_dsoname(alf.map, stdout);
593 printf(")");
594 }
562 putchar('/'); 595 putchar('/');
563 symbol__fprintf_symname_offs(alt.sym, &alt, stdout); 596 symbol__fprintf_symname_offs(alt.sym, &alt, stdout);
597 if (PRINT_FIELD(DSO)) {
598 printf("(");
599 map__fprintf_dsoname(alt.map, stdout);
600 printf(")");
601 }
564 printf("/%c/%c/%c/%d ", 602 printf("/%c/%c/%c/%d ",
565 mispred_str( br->entries + i), 603 mispred_str( br->entries + i),
566 br->entries[i].flags.in_tx? 'X' : '-', 604 br->entries[i].flags.in_tx? 'X' : '-',
@@ -569,6 +607,51 @@ static void print_sample_brstacksym(struct perf_sample *sample,
569 } 607 }
570} 608}
571 609
610static void print_sample_brstackoff(struct perf_sample *sample,
611 struct thread *thread,
612 struct perf_event_attr *attr)
613{
614 struct branch_stack *br = sample->branch_stack;
615 struct addr_location alf, alt;
616 u64 i, from, to;
617
618 if (!(br && br->nr))
619 return;
620
621 for (i = 0; i < br->nr; i++) {
622
623 memset(&alf, 0, sizeof(alf));
624 memset(&alt, 0, sizeof(alt));
625 from = br->entries[i].from;
626 to = br->entries[i].to;
627
628 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf);
629 if (alf.map && !alf.map->dso->adjust_symbols)
630 from = map__map_ip(alf.map, from);
631
632 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
633 if (alt.map && !alt.map->dso->adjust_symbols)
634 to = map__map_ip(alt.map, to);
635
636 printf("0x%"PRIx64, from);
637 if (PRINT_FIELD(DSO)) {
638 printf("(");
639 map__fprintf_dsoname(alf.map, stdout);
640 printf(")");
641 }
642 printf("/0x%"PRIx64, to);
643 if (PRINT_FIELD(DSO)) {
644 printf("(");
645 map__fprintf_dsoname(alt.map, stdout);
646 printf(")");
647 }
648 printf("/%c/%c/%c/%d ",
649 mispred_str(br->entries + i),
650 br->entries[i].flags.in_tx ? 'X' : '-',
651 br->entries[i].flags.abort ? 'A' : '-',
652 br->entries[i].flags.cycles);
653 }
654}
572#define MAXBB 16384UL 655#define MAXBB 16384UL
573 656
574static int grab_bb(u8 *buffer, u64 start, u64 end, 657static int grab_bb(u8 *buffer, u64 start, u64 end,
@@ -1187,9 +1270,11 @@ static void process_event(struct perf_script *script,
1187 print_sample_iregs(sample, attr); 1270 print_sample_iregs(sample, attr);
1188 1271
1189 if (PRINT_FIELD(BRSTACK)) 1272 if (PRINT_FIELD(BRSTACK))
1190 print_sample_brstack(sample); 1273 print_sample_brstack(sample, thread, attr);
1191 else if (PRINT_FIELD(BRSTACKSYM)) 1274 else if (PRINT_FIELD(BRSTACKSYM))
1192 print_sample_brstacksym(sample, thread); 1275 print_sample_brstacksym(sample, thread, attr);
1276 else if (PRINT_FIELD(BRSTACKOFF))
1277 print_sample_brstackoff(sample, thread, attr);
1193 1278
1194 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) 1279 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
1195 print_sample_bpf_output(sample); 1280 print_sample_bpf_output(sample);
@@ -1727,6 +1812,7 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1727 int rc = 0; 1812 int rc = 0;
1728 char *str = strdup(arg); 1813 char *str = strdup(arg);
1729 int type = -1; 1814 int type = -1;
1815 enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
1730 1816
1731 if (!str) 1817 if (!str)
1732 return -ENOMEM; 1818 return -ENOMEM;
@@ -1772,6 +1858,10 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1772 goto out; 1858 goto out;
1773 } 1859 }
1774 1860
1861 /* Don't override defaults for +- */
1862 if (strchr(str, '+') || strchr(str, '-'))
1863 goto parse;
1864
1775 if (output_set_by_user()) 1865 if (output_set_by_user())
1776 pr_warning("Overriding previous field request for all events.\n"); 1866 pr_warning("Overriding previous field request for all events.\n");
1777 1867
@@ -1782,13 +1872,30 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1782 } 1872 }
1783 } 1873 }
1784 1874
1875parse:
1785 for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) { 1876 for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
1877 if (*tok == '+') {
1878 if (change == SET)
1879 goto out_badmix;
1880 change = ADD;
1881 tok++;
1882 } else if (*tok == '-') {
1883 if (change == SET)
1884 goto out_badmix;
1885 change = REMOVE;
1886 tok++;
1887 } else {
1888 if (change != SET && change != DEFAULT)
1889 goto out_badmix;
1890 change = SET;
1891 }
1892
1786 for (i = 0; i < imax; ++i) { 1893 for (i = 0; i < imax; ++i) {
1787 if (strcmp(tok, all_output_options[i].str) == 0) 1894 if (strcmp(tok, all_output_options[i].str) == 0)
1788 break; 1895 break;
1789 } 1896 }
1790 if (i == imax && strcmp(tok, "flags") == 0) { 1897 if (i == imax && strcmp(tok, "flags") == 0) {
1791 print_flags = true; 1898 print_flags = change == REMOVE ? false : true;
1792 continue; 1899 continue;
1793 } 1900 }
1794 if (i == imax) { 1901 if (i == imax) {
@@ -1805,8 +1912,12 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1805 if (output[j].invalid_fields & all_output_options[i].field) { 1912 if (output[j].invalid_fields & all_output_options[i].field) {
1806 pr_warning("\'%s\' not valid for %s events. Ignoring.\n", 1913 pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
1807 all_output_options[i].str, event_type(j)); 1914 all_output_options[i].str, event_type(j));
1808 } else 1915 } else {
1809 output[j].fields |= all_output_options[i].field; 1916 if (change == REMOVE)
1917 output[j].fields &= ~all_output_options[i].field;
1918 else
1919 output[j].fields |= all_output_options[i].field;
1920 }
1810 } 1921 }
1811 } else { 1922 } else {
1812 if (output[type].invalid_fields & all_output_options[i].field) { 1923 if (output[type].invalid_fields & all_output_options[i].field) {
@@ -1826,7 +1937,11 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
1826 "Events will not be displayed.\n", event_type(type)); 1937 "Events will not be displayed.\n", event_type(type));
1827 } 1938 }
1828 } 1939 }
1940 goto out;
1829 1941
1942out_badmix:
1943 fprintf(stderr, "Cannot mix +-field with overridden fields\n");
1944 rc = -EINVAL;
1830out: 1945out:
1831 free(str); 1946 free(str);
1832 return rc; 1947 return rc;
@@ -2444,6 +2559,7 @@ int cmd_script(int argc, const char **argv)
2444 symbol__config_symfs), 2559 symbol__config_symfs),
2445 OPT_CALLBACK('F', "fields", NULL, "str", 2560 OPT_CALLBACK('F', "fields", NULL, "str",
2446 "comma separated output fields prepend with 'type:'. " 2561 "comma separated output fields prepend with 'type:'. "
2562 "+field to add and -field to remove."
2447 "Valid types: hw,sw,trace,raw. " 2563 "Valid types: hw,sw,trace,raw. "
2448 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 2564 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
2449 "addr,symoff,period,iregs,brstack,brstacksym,flags," 2565 "addr,symoff,period,iregs,brstack,brstacksym,flags,"
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 10b6362ca0bf..2bcfa46913c8 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -134,7 +134,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
134 return err; 134 return err;
135 } 135 }
136 136
137 err = symbol__disassemble(sym, map, NULL, 0); 137 err = symbol__disassemble(sym, map, NULL, 0, NULL);
138 if (err == 0) { 138 if (err == 0) {
139out_assign: 139out_assign:
140 top->sym_filter_entry = he; 140 top->sym_filter_entry = he;
diff --git a/tools/perf/jvmti/jvmti_agent.h b/tools/perf/jvmti/jvmti_agent.h
index bedf5d0ba9ff..c53a41f48b63 100644
--- a/tools/perf/jvmti/jvmti_agent.h
+++ b/tools/perf/jvmti/jvmti_agent.h
@@ -5,8 +5,6 @@
5#include <stdint.h> 5#include <stdint.h>
6#include <jvmti.h> 6#include <jvmti.h>
7 7
8#define __unused __attribute__((unused))
9
10#if defined(__cplusplus) 8#if defined(__cplusplus)
11extern "C" { 9extern "C" {
12#endif 10#endif
diff --git a/tools/perf/jvmti/libjvmti.c b/tools/perf/jvmti/libjvmti.c
index 5612641c69b4..6d710904c837 100644
--- a/tools/perf/jvmti/libjvmti.c
+++ b/tools/perf/jvmti/libjvmti.c
@@ -1,3 +1,4 @@
1#include <linux/compiler.h>
1#include <sys/types.h> 2#include <sys/types.h>
2#include <stdio.h> 3#include <stdio.h>
3#include <string.h> 4#include <string.h>
@@ -238,7 +239,7 @@ code_generated_cb(jvmtiEnv *jvmti,
238} 239}
239 240
240JNIEXPORT jint JNICALL 241JNIEXPORT jint JNICALL
241Agent_OnLoad(JavaVM *jvm, char *options, void *reserved __unused) 242Agent_OnLoad(JavaVM *jvm, char *options, void *reserved __maybe_unused)
242{ 243{
243 jvmtiEventCallbacks cb; 244 jvmtiEventCallbacks cb;
244 jvmtiCapabilities caps1; 245 jvmtiCapabilities caps1;
@@ -313,7 +314,7 @@ Agent_OnLoad(JavaVM *jvm, char *options, void *reserved __unused)
313} 314}
314 315
315JNIEXPORT void JNICALL 316JNIEXPORT void JNICALL
316Agent_OnUnload(JavaVM *jvm __unused) 317Agent_OnUnload(JavaVM *jvm __maybe_unused)
317{ 318{
318 int ret; 319 int ret;
319 320
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index baa073f38334..bd0aabb2bd0f 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -48,10 +48,6 @@
48#include "json.h" 48#include "json.h"
49#include "jevents.h" 49#include "jevents.h"
50 50
51#ifndef __maybe_unused
52#define __maybe_unused __attribute__((unused))
53#endif
54
55int verbose; 51int verbose;
56char *prog; 52char *prog;
57 53
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
index 8ba2c4618fe9..39bbb97cd30a 100644
--- a/tools/perf/tests/bp_signal.c
+++ b/tools/perf/tests/bp_signal.c
@@ -62,8 +62,7 @@ static void __test_function(volatile long *ptr)
62} 62}
63#endif 63#endif
64 64
65__attribute__ ((noinline)) 65static noinline int test_function(void)
66static int test_function(void)
67{ 66{
68 __test_function(&the_var); 67 __test_function(&the_var);
69 the_var++; 68 the_var++;
diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c
index 89f92fa67cc4..3b1ac6f31b15 100644
--- a/tools/perf/tests/bp_signal_overflow.c
+++ b/tools/perf/tests/bp_signal_overflow.c
@@ -28,8 +28,7 @@
28 28
29static int overflows; 29static int overflows;
30 30
31__attribute__ ((noinline)) 31static noinline int test_function(void)
32static int test_function(void)
33{ 32{
34 return time(NULL); 33 return time(NULL);
35} 34}
diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c
index 7230e62c70fc..b4ebc75e25ae 100644
--- a/tools/perf/tests/bpf-script-test-prologue.c
+++ b/tools/perf/tests/bpf-script-test-prologue.c
@@ -10,6 +10,15 @@
10 10
11#include <uapi/linux/fs.h> 11#include <uapi/linux/fs.h>
12 12
13/*
14 * If CONFIG_PROFILE_ALL_BRANCHES is selected,
15 * 'if' is redefined after include kernel header.
16 * Recover 'if' for BPF object code.
17 */
18#ifdef if
19# undef if
20#endif
21
13#define FMODE_READ 0x1 22#define FMODE_READ 0x1
14#define FMODE_WRITE 0x2 23#define FMODE_WRITE 0x2
15 24
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c
index dfe5c89e2049..3e56d08f7995 100644
--- a/tools/perf/tests/dwarf-unwind.c
+++ b/tools/perf/tests/dwarf-unwind.c
@@ -76,8 +76,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
76 return strcmp((const char *) symbol, funcs[idx]); 76 return strcmp((const char *) symbol, funcs[idx]);
77} 77}
78 78
79__attribute__ ((noinline)) 79static noinline int unwind_thread(struct thread *thread)
80static int unwind_thread(struct thread *thread)
81{ 80{
82 struct perf_sample sample; 81 struct perf_sample sample;
83 unsigned long cnt = 0; 82 unsigned long cnt = 0;
@@ -108,8 +107,7 @@ static int unwind_thread(struct thread *thread)
108 107
109static int global_unwind_retval = -INT_MAX; 108static int global_unwind_retval = -INT_MAX;
110 109
111__attribute__ ((noinline)) 110static noinline int compare(void *p1, void *p2)
112static int compare(void *p1, void *p2)
113{ 111{
114 /* Any possible value should be 'thread' */ 112 /* Any possible value should be 'thread' */
115 struct thread *thread = *(struct thread **)p1; 113 struct thread *thread = *(struct thread **)p1;
@@ -128,8 +126,7 @@ static int compare(void *p1, void *p2)
128 return p1 - p2; 126 return p1 - p2;
129} 127}
130 128
131__attribute__ ((noinline)) 129static noinline int krava_3(struct thread *thread)
132static int krava_3(struct thread *thread)
133{ 130{
134 struct thread *array[2] = {thread, thread}; 131 struct thread *array[2] = {thread, thread};
135 void *fp = &bsearch; 132 void *fp = &bsearch;
@@ -147,14 +144,12 @@ static int krava_3(struct thread *thread)
147 return global_unwind_retval; 144 return global_unwind_retval;
148} 145}
149 146
150__attribute__ ((noinline)) 147static noinline int krava_2(struct thread *thread)
151static int krava_2(struct thread *thread)
152{ 148{
153 return krava_3(thread); 149 return krava_3(thread);
154} 150}
155 151
156__attribute__ ((noinline)) 152static noinline int krava_1(struct thread *thread)
157static int krava_1(struct thread *thread)
158{ 153{
159 return krava_2(thread); 154 return krava_2(thread);
160} 155}
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index d990ad08a3c6..27f41f28dcb4 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -46,12 +46,15 @@ static struct annotate_browser_opt {
46 .jump_arrows = true, 46 .jump_arrows = true,
47}; 47};
48 48
49struct arch;
50
49struct annotate_browser { 51struct annotate_browser {
50 struct ui_browser b; 52 struct ui_browser b;
51 struct rb_root entries; 53 struct rb_root entries;
52 struct rb_node *curr_hot; 54 struct rb_node *curr_hot;
53 struct disasm_line *selection; 55 struct disasm_line *selection;
54 struct disasm_line **offsets; 56 struct disasm_line **offsets;
57 struct arch *arch;
55 int nr_events; 58 int nr_events;
56 u64 start; 59 u64 start;
57 int nr_asm_entries; 60 int nr_asm_entries;
@@ -125,43 +128,57 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
125 int i, pcnt_width = annotate_browser__pcnt_width(ab); 128 int i, pcnt_width = annotate_browser__pcnt_width(ab);
126 double percent_max = 0.0; 129 double percent_max = 0.0;
127 char bf[256]; 130 char bf[256];
131 bool show_title = false;
128 132
129 for (i = 0; i < ab->nr_events; i++) { 133 for (i = 0; i < ab->nr_events; i++) {
130 if (bdl->samples[i].percent > percent_max) 134 if (bdl->samples[i].percent > percent_max)
131 percent_max = bdl->samples[i].percent; 135 percent_max = bdl->samples[i].percent;
132 } 136 }
133 137
138 if ((row == 0) && (dl->offset == -1 || percent_max == 0.0)) {
139 if (ab->have_cycles) {
140 if (dl->ipc == 0.0 && dl->cycles == 0)
141 show_title = true;
142 } else
143 show_title = true;
144 }
145
134 if (dl->offset != -1 && percent_max != 0.0) { 146 if (dl->offset != -1 && percent_max != 0.0) {
135 if (percent_max != 0.0) { 147 for (i = 0; i < ab->nr_events; i++) {
136 for (i = 0; i < ab->nr_events; i++) { 148 ui_browser__set_percent_color(browser,
137 ui_browser__set_percent_color(browser, 149 bdl->samples[i].percent,
138 bdl->samples[i].percent, 150 current_entry);
139 current_entry); 151 if (annotate_browser__opts.show_total_period) {
140 if (annotate_browser__opts.show_total_period) { 152 ui_browser__printf(browser, "%6" PRIu64 " ",
141 ui_browser__printf(browser, "%6" PRIu64 " ", 153 bdl->samples[i].nr);
142 bdl->samples[i].nr); 154 } else {
143 } else { 155 ui_browser__printf(browser, "%6.2f ",
144 ui_browser__printf(browser, "%6.2f ", 156 bdl->samples[i].percent);
145 bdl->samples[i].percent);
146 }
147 } 157 }
148 } else {
149 ui_browser__write_nstring(browser, " ", 7 * ab->nr_events);
150 } 158 }
151 } else { 159 } else {
152 ui_browser__set_percent_color(browser, 0, current_entry); 160 ui_browser__set_percent_color(browser, 0, current_entry);
153 ui_browser__write_nstring(browser, " ", 7 * ab->nr_events); 161
162 if (!show_title)
163 ui_browser__write_nstring(browser, " ", 7 * ab->nr_events);
164 else
165 ui_browser__printf(browser, "%*s", 7, "Percent");
154 } 166 }
155 if (ab->have_cycles) { 167 if (ab->have_cycles) {
156 if (dl->ipc) 168 if (dl->ipc)
157 ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, dl->ipc); 169 ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, dl->ipc);
158 else 170 else if (!show_title)
159 ui_browser__write_nstring(browser, " ", IPC_WIDTH); 171 ui_browser__write_nstring(browser, " ", IPC_WIDTH);
172 else
173 ui_browser__printf(browser, "%*s ", IPC_WIDTH - 1, "IPC");
174
160 if (dl->cycles) 175 if (dl->cycles)
161 ui_browser__printf(browser, "%*" PRIu64 " ", 176 ui_browser__printf(browser, "%*" PRIu64 " ",
162 CYCLES_WIDTH - 1, dl->cycles); 177 CYCLES_WIDTH - 1, dl->cycles);
163 else 178 else if (!show_title)
164 ui_browser__write_nstring(browser, " ", CYCLES_WIDTH); 179 ui_browser__write_nstring(browser, " ", CYCLES_WIDTH);
180 else
181 ui_browser__printf(browser, "%*s ", CYCLES_WIDTH - 1, "Cycle");
165 } 182 }
166 183
167 SLsmg_write_char(' '); 184 SLsmg_write_char(' ');
@@ -1056,7 +1073,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
1056 (nr_pcnt - 1); 1073 (nr_pcnt - 1);
1057 } 1074 }
1058 1075
1059 err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), sizeof_bdl); 1076 err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel),
1077 sizeof_bdl, &browser.arch);
1060 if (err) { 1078 if (err) {
1061 char msg[BUFSIZ]; 1079 char msg[BUFSIZ];
1062 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); 1080 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c
index e99ba86158d2..d903fd493416 100644
--- a/tools/perf/ui/gtk/annotate.c
+++ b/tools/perf/ui/gtk/annotate.c
@@ -168,7 +168,8 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
168 if (map->dso->annotate_warned) 168 if (map->dso->annotate_warned)
169 return -1; 169 return -1;
170 170
171 err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), 0); 171 err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel),
172 0, NULL);
172 if (err) { 173 if (err) {
173 char msg[BUFSIZ]; 174 char msg[BUFSIZ];
174 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); 175 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index ddbd56df9187..be1caabb9290 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1379,7 +1379,9 @@ static const char *annotate__norm_arch(const char *arch_name)
1379 return normalize_arch((char *)arch_name); 1379 return normalize_arch((char *)arch_name);
1380} 1380}
1381 1381
1382int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize) 1382int symbol__disassemble(struct symbol *sym, struct map *map,
1383 const char *arch_name, size_t privsize,
1384 struct arch **parch)
1383{ 1385{
1384 struct dso *dso = map->dso; 1386 struct dso *dso = map->dso;
1385 char command[PATH_MAX * 2]; 1387 char command[PATH_MAX * 2];
@@ -1405,6 +1407,9 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
1405 if (arch == NULL) 1407 if (arch == NULL)
1406 return -ENOTSUP; 1408 return -ENOTSUP;
1407 1409
1410 if (parch)
1411 *parch = arch;
1412
1408 if (arch->init) { 1413 if (arch->init) {
1409 err = arch->init(arch); 1414 err = arch->init(arch);
1410 if (err) { 1415 if (err) {
@@ -1901,7 +1906,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
1901 struct rb_root source_line = RB_ROOT; 1906 struct rb_root source_line = RB_ROOT;
1902 u64 len; 1907 u64 len;
1903 1908
1904 if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), 0) < 0) 1909 if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel),
1910 0, NULL) < 0)
1905 return -1; 1911 return -1;
1906 1912
1907 len = symbol__size(sym); 1913 len = symbol__size(sym);
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 948aa8e6fd39..21055034aedd 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -158,7 +158,9 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
158int symbol__alloc_hist(struct symbol *sym); 158int symbol__alloc_hist(struct symbol *sym);
159void symbol__annotate_zero_histograms(struct symbol *sym); 159void symbol__annotate_zero_histograms(struct symbol *sym);
160 160
161int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize); 161int symbol__disassemble(struct symbol *sym, struct map *map,
162 const char *arch_name, size_t privsize,
163 struct arch **parch);
162 164
163enum symbol_disassemble_errno { 165enum symbol_disassemble_errno {
164 SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, 166 SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0,
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 0328f297a748..0175765c05b9 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -5,6 +5,7 @@
5#include <subcmd/pager.h> 5#include <subcmd/pager.h>
6#include "../ui/ui.h" 6#include "../ui/ui.h"
7 7
8#include <linux/compiler.h>
8#include <linux/string.h> 9#include <linux/string.h>
9 10
10#define CMD_EXEC_PATH "--exec-path" 11#define CMD_EXEC_PATH "--exec-path"
@@ -24,6 +25,6 @@ static inline int is_absolute_path(const char *path)
24 return path[0] == '/'; 25 return path[0] == '/';
25} 26}
26 27
27char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 28char *mkpath(const char *fmt, ...) __printf(1, 2);
28 29
29#endif /* __PERF_CACHE_H */ 30#endif /* __PERF_CACHE_H */
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 8a23ea1a71c7..c818bdb1c1ab 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -4,6 +4,7 @@
4 4
5#include <stdbool.h> 5#include <stdbool.h>
6#include <string.h> 6#include <string.h>
7#include <linux/compiler.h>
7#include "event.h" 8#include "event.h"
8#include "../ui/helpline.h" 9#include "../ui/helpline.h"
9#include "../ui/progress.h" 10#include "../ui/progress.h"
@@ -40,16 +41,16 @@ extern int debug_data_convert;
40 41
41#define STRERR_BUFSIZE 128 /* For the buffer size of str_error_r */ 42#define STRERR_BUFSIZE 128 /* For the buffer size of str_error_r */
42 43
43int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); 44int dump_printf(const char *fmt, ...) __printf(1, 2);
44void trace_event(union perf_event *event); 45void trace_event(union perf_event *event);
45 46
46int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); 47int ui__error(const char *format, ...) __printf(1, 2);
47int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); 48int ui__warning(const char *format, ...) __printf(1, 2);
48 49
49void pr_stat(const char *fmt, ...); 50void pr_stat(const char *fmt, ...);
50 51
51int eprintf(int level, int var, const char *fmt, ...) __attribute__((format(printf, 3, 4))); 52int eprintf(int level, int var, const char *fmt, ...) __printf(3, 4);
52int eprintf_time(int level, int var, u64 t, const char *fmt, ...) __attribute__((format(printf, 4, 5))); 53int eprintf_time(int level, int var, u64 t, const char *fmt, ...) __printf(4, 5);
53int veprintf(int level, int var, const char *fmt, va_list args); 54int veprintf(int level, int var, const char *fmt, va_list args);
54 55
55int perf_debug_option(const char *str); 56int perf_debug_option(const char *str);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 94cea4398a13..8d601fbdd8d6 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -1,6 +1,7 @@
1#ifndef __PERF_EVLIST_H 1#ifndef __PERF_EVLIST_H
2#define __PERF_EVLIST_H 1 2#define __PERF_EVLIST_H 1
3 3
4#include <linux/compiler.h>
4#include <linux/kernel.h> 5#include <linux/kernel.h>
5#include <linux/refcount.h> 6#include <linux/refcount.h>
6#include <linux/list.h> 7#include <linux/list.h>
@@ -34,7 +35,7 @@ struct perf_mmap {
34 refcount_t refcnt; 35 refcount_t refcnt;
35 u64 prev; 36 u64 prev;
36 struct auxtrace_mmap auxtrace_mmap; 37 struct auxtrace_mmap auxtrace_mmap;
37 char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8))); 38 char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8);
38}; 39};
39 40
40static inline size_t 41static inline size_t
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index cda44b0e821c..7f78f27f5382 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -15,6 +15,7 @@
15#include <traceevent/event-parse.h> 15#include <traceevent/event-parse.h>
16#include <linux/hw_breakpoint.h> 16#include <linux/hw_breakpoint.h>
17#include <linux/perf_event.h> 17#include <linux/perf_event.h>
18#include <linux/compiler.h>
18#include <linux/err.h> 19#include <linux/err.h>
19#include <sys/ioctl.h> 20#include <sys/ioctl.h>
20#include <sys/resource.h> 21#include <sys/resource.h>
@@ -1441,7 +1442,7 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
1441} 1442}
1442 1443
1443static int __open_attr__fprintf(FILE *fp, const char *name, const char *val, 1444static int __open_attr__fprintf(FILE *fp, const char *name, const char *val,
1444 void *priv __attribute__((unused))) 1445 void *priv __maybe_unused)
1445{ 1446{
1446 return fprintf(fp, " %-32s %s\n", name, val); 1447 return fprintf(fp, " %-32s %s\n", name, val);
1447} 1448}
diff --git a/tools/perf/util/genelf_debug.c b/tools/perf/util/genelf_debug.c
index 5980f7d256b1..40789d8603d0 100644
--- a/tools/perf/util/genelf_debug.c
+++ b/tools/perf/util/genelf_debug.c
@@ -11,6 +11,7 @@
11 * @remark Copyright 2007 OProfile authors 11 * @remark Copyright 2007 OProfile authors
12 * @author Philippe Elie 12 * @author Philippe Elie
13 */ 13 */
14#include <linux/compiler.h>
14#include <sys/types.h> 15#include <sys/types.h>
15#include <stdio.h> 16#include <stdio.h>
16#include <getopt.h> 17#include <getopt.h>
@@ -125,7 +126,7 @@ struct debug_line_header {
125 * and filesize, last entry is followed by en empty string. 126 * and filesize, last entry is followed by en empty string.
126 */ 127 */
127 /* follow the first program statement */ 128 /* follow the first program statement */
128} __attribute__((packed)); 129} __packed;
129 130
130/* DWARF 2 spec talk only about one possible compilation unit header while 131/* DWARF 2 spec talk only about one possible compilation unit header while
131 * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not 132 * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not
@@ -138,7 +139,7 @@ struct compilation_unit_header {
138 uhalf version; 139 uhalf version;
139 uword debug_abbrev_offset; 140 uword debug_abbrev_offset;
140 ubyte pointer_size; 141 ubyte pointer_size;
141} __attribute__((packed)); 142} __packed;
142 143
143#define DW_LNS_num_opcode (DW_LNS_set_isa + 1) 144#define DW_LNS_num_opcode (DW_LNS_set_isa + 1)
144 145
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index b5baff3007bb..76ed7d03e500 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -8,6 +8,7 @@
8#include <unistd.h> 8#include <unistd.h>
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <linux/compiler.h>
11#include <linux/list.h> 12#include <linux/list.h>
12#include <linux/kernel.h> 13#include <linux/kernel.h>
13#include <linux/bitops.h> 14#include <linux/bitops.h>
@@ -1274,7 +1275,7 @@ error:
1274} 1275}
1275 1276
1276static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val, 1277static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val,
1277 void *priv __attribute__((unused))) 1278 void *priv __maybe_unused)
1278{ 1279{
1279 return fprintf(fp, ", %s = %s", name, val); 1280 return fprintf(fp, ", %s = %s", name, val);
1280} 1281}
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index b2834ac7b1f5..218ee2bac9a5 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -866,8 +866,6 @@ static void intel_bts_print_info(u64 *arr, int start, int finish)
866 fprintf(stdout, intel_bts_info_fmts[i], arr[i]); 866 fprintf(stdout, intel_bts_info_fmts[i], arr[i]);
867} 867}
868 868
869u64 intel_bts_auxtrace_info_priv[INTEL_BTS_AUXTRACE_PRIV_SIZE];
870
871int intel_bts_process_auxtrace_info(union perf_event *event, 869int intel_bts_process_auxtrace_info(union perf_event *event,
872 struct perf_session *session) 870 struct perf_session *session)
873{ 871{
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-log.h b/tools/perf/util/intel-pt-decoder/intel-pt-log.h
index debe751dc3d6..45b64f93f358 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-log.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-log.h
@@ -16,6 +16,7 @@
16#ifndef INCLUDE__INTEL_PT_LOG_H__ 16#ifndef INCLUDE__INTEL_PT_LOG_H__
17#define INCLUDE__INTEL_PT_LOG_H__ 17#define INCLUDE__INTEL_PT_LOG_H__
18 18
19#include <linux/compiler.h>
19#include <stdint.h> 20#include <stdint.h>
20#include <inttypes.h> 21#include <inttypes.h>
21 22
@@ -34,8 +35,7 @@ void __intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip);
34void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn, 35void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn,
35 uint64_t ip); 36 uint64_t ip);
36 37
37__attribute__((format(printf, 1, 2))) 38void __intel_pt_log(const char *fmt, ...) __printf(1, 2);
38void __intel_pt_log(const char *fmt, ...);
39 39
40#define intel_pt_log(fmt, ...) \ 40#define intel_pt_log(fmt, ...) \
41 do { \ 41 do { \
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index ea7f450dc609..389e9729331f 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -2,6 +2,7 @@
2#define __PMU_H 2#define __PMU_H
3 3
4#include <linux/bitmap.h> 4#include <linux/bitmap.h>
5#include <linux/compiler.h>
5#include <linux/perf_event.h> 6#include <linux/perf_event.h>
6#include <stdbool.h> 7#include <stdbool.h>
7#include "evsel.h" 8#include "evsel.h"
@@ -83,8 +84,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet,
83 bool long_desc, bool details_flag); 84 bool long_desc, bool details_flag);
84bool pmu_have_event(const char *pname, const char *name); 85bool pmu_have_event(const char *pname, const char *name);
85 86
86int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, 87int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, ...) __scanf(3, 4);
87 ...) __attribute__((format(scanf, 3, 4)));
88 88
89int perf_pmu__test(void); 89int perf_pmu__test(void);
90 90
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 373842656fb6..5812947418dd 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -1,6 +1,7 @@
1#ifndef _PROBE_EVENT_H 1#ifndef _PROBE_EVENT_H
2#define _PROBE_EVENT_H 2#define _PROBE_EVENT_H
3 3
4#include <linux/compiler.h>
4#include <stdbool.h> 5#include <stdbool.h>
5#include "intlist.h" 6#include "intlist.h"
6 7
@@ -171,8 +172,7 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
171 struct symbol *sym); 172 struct symbol *sym);
172 173
173/* If there is no space to write, returns -E2BIG. */ 174/* If there is no space to write, returns -E2BIG. */
174int e_snprintf(char *str, size_t size, const char *format, ...) 175int e_snprintf(char *str, size_t size, const char *format, ...) __printf(3, 4);
175 __attribute__((format(printf, 3, 4)));
176 176
177/* Maximum index number of event-name postfix */ 177/* Maximum index number of event-name postfix */
178#define MAX_EVENT_INDEX 1024 178#define MAX_EVENT_INDEX 1024
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 40de3cb40d21..57b7a00e6f16 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -28,6 +28,7 @@
28#include <stdbool.h> 28#include <stdbool.h>
29#include <errno.h> 29#include <errno.h>
30#include <linux/bitmap.h> 30#include <linux/bitmap.h>
31#include <linux/compiler.h>
31#include <linux/time64.h> 32#include <linux/time64.h>
32 33
33#include "../../perf.h" 34#include "../../perf.h"
@@ -84,7 +85,7 @@ struct tables {
84 85
85static struct tables tables_global; 86static struct tables tables_global;
86 87
87static void handler_call_die(const char *handler_name) NORETURN; 88static void handler_call_die(const char *handler_name) __noreturn;
88static void handler_call_die(const char *handler_name) 89static void handler_call_die(const char *handler_name)
89{ 90{
90 PyErr_Print(); 91 PyErr_Print();
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h
index 318424ea561d..802d743378af 100644
--- a/tools/perf/util/strbuf.h
+++ b/tools/perf/util/strbuf.h
@@ -42,6 +42,7 @@
42#include <stdarg.h> 42#include <stdarg.h>
43#include <stddef.h> 43#include <stddef.h>
44#include <string.h> 44#include <string.h>
45#include <linux/compiler.h>
45#include <sys/types.h> 46#include <sys/types.h>
46 47
47extern char strbuf_slopbuf[]; 48extern char strbuf_slopbuf[];
@@ -85,8 +86,7 @@ static inline int strbuf_addstr(struct strbuf *sb, const char *s) {
85 return strbuf_add(sb, s, strlen(s)); 86 return strbuf_add(sb, s, strlen(s));
86} 87}
87 88
88__attribute__((format(printf,2,3))) 89int strbuf_addf(struct strbuf *sb, const char *fmt, ...) __printf(2, 3);
89int strbuf_addf(struct strbuf *sb, const char *fmt, ...);
90 90
91/* XXX: if read fails, any partial read is undone */ 91/* XXX: if read fails, any partial read is undone */
92ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); 92ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c
index 996046a66fe5..aacb65e079aa 100644
--- a/tools/perf/util/usage.c
+++ b/tools/perf/util/usage.c
@@ -16,13 +16,13 @@ static void report(const char *prefix, const char *err, va_list params)
16 fprintf(stderr, " %s%s\n", prefix, msg); 16 fprintf(stderr, " %s%s\n", prefix, msg);
17} 17}
18 18
19static NORETURN void usage_builtin(const char *err) 19static __noreturn void usage_builtin(const char *err)
20{ 20{
21 fprintf(stderr, "\n Usage: %s\n", err); 21 fprintf(stderr, "\n Usage: %s\n", err);
22 exit(129); 22 exit(129);
23} 23}
24 24
25static NORETURN void die_builtin(const char *err, va_list params) 25static __noreturn void die_builtin(const char *err, va_list params)
26{ 26{
27 report(" Fatal: ", err, params); 27 report(" Fatal: ", err, params);
28 exit(128); 28 exit(128);
@@ -40,7 +40,7 @@ static void warn_builtin(const char *warn, va_list params)
40 40
41/* If we are in a dlopen()ed .so write to a global variable would segfault 41/* If we are in a dlopen()ed .so write to a global variable would segfault
42 * (ugh), so keep things static. */ 42 * (ugh), so keep things static. */
43static void (*usage_routine)(const char *err) NORETURN = usage_builtin; 43static void (*usage_routine)(const char *err) __noreturn = usage_builtin;
44static void (*error_routine)(const char *err, va_list params) = error_builtin; 44static void (*error_routine)(const char *err, va_list params) = error_builtin;
45static void (*warn_routine)(const char *err, va_list params) = warn_builtin; 45static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
46 46
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 5dfb9bb6482d..21c6db173bcc 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -11,22 +11,14 @@
11#include <stddef.h> 11#include <stddef.h>
12#include <stdlib.h> 12#include <stdlib.h>
13#include <stdarg.h> 13#include <stdarg.h>
14#include <linux/compiler.h>
14#include <linux/types.h> 15#include <linux/types.h>
15 16
16#ifdef __GNUC__
17#define NORETURN __attribute__((__noreturn__))
18#else
19#define NORETURN
20#ifndef __attribute__
21#define __attribute__(x)
22#endif
23#endif
24
25/* General helper functions */ 17/* General helper functions */
26void usage(const char *err) NORETURN; 18void usage(const char *err) __noreturn;
27void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); 19void die(const char *err, ...) __noreturn __printf(1, 2);
28int error(const char *err, ...) __attribute__((format (printf, 1, 2))); 20int error(const char *err, ...) __printf(1, 2);
29void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); 21void warning(const char *err, ...) __printf(1, 2);
30 22
31void set_warning_routine(void (*routine)(const char *err, va_list params)); 23void set_warning_routine(void (*routine)(const char *err, va_list params));
32 24