aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2018-10-09 01:22:04 -0400
committerIngo Molnar <mingo@kernel.org>2018-10-09 01:23:23 -0400
commit8f51ba8e604e6b35105f120cd69018b14ade84d2 (patch)
treebce63ed0b2eb15b54e9dec30dd4df044c6c54ad4
parent6364cb2218348cd5fba975e1ab5b7f37dee9adc4 (diff)
parentbb3dd7e7c4d5e024d607c0ec06c2a2fb9408cc99 (diff)
Merge tag 'perf-core-for-mingo-4.20-20181008' 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: - Fix building the python bindings with python3, which fixes some problems with building with clang on Clear Linux (Eduardo Habkost) - Fix coverity warnings, fixing up some error paths and plugging some temporary small buffer leaks (Sanskriti Sharma) - Adopt a wrapper for strerror_r() for the same reasons as recently for libbpf (Steven Rostedt) - S390 does not support watchpoints in perf test 22', check if that test is supported by the arch. (Thomas Richter) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/include/linux/bitops.h7
-rw-r--r--tools/include/linux/bits.h26
-rw-r--r--tools/lib/traceevent/Build2
-rw-r--r--tools/lib/traceevent/event-parse-api.c275
-rw-r--r--tools/lib/traceevent/event-parse-local.h92
-rw-r--r--tools/lib/traceevent/event-parse.c32
-rw-r--r--tools/lib/traceevent/event-parse.h228
-rw-r--r--tools/lib/traceevent/event-plugin.c1
-rw-r--r--tools/lib/traceevent/parse-filter.c1
-rw-r--r--tools/lib/traceevent/tep_strerror.c53
-rwxr-xr-xtools/perf/check-headers.sh1
-rw-r--r--tools/perf/tests/builtin-test.c1
-rw-r--r--tools/perf/tests/tests.h1
-rw-r--r--tools/perf/tests/wp.c12
-rw-r--r--tools/perf/util/auxtrace.h1
-rw-r--r--tools/perf/util/setup.py16
-rw-r--r--tools/perf/util/strbuf.c10
-rw-r--r--tools/perf/util/trace-event-info.c2
-rw-r--r--tools/perf/util/trace-event-parse.c26
-rw-r--r--tools/perf/util/trace-event-read.c11
20 files changed, 539 insertions, 259 deletions
diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h
index acc704bd3998..0b0ef3abc966 100644
--- a/tools/include/linux/bitops.h
+++ b/tools/include/linux/bitops.h
@@ -3,8 +3,6 @@
3#define _TOOLS_LINUX_BITOPS_H_ 3#define _TOOLS_LINUX_BITOPS_H_
4 4
5#include <asm/types.h> 5#include <asm/types.h>
6#include <linux/compiler.h>
7
8#ifndef __WORDSIZE 6#ifndef __WORDSIZE
9#define __WORDSIZE (__SIZEOF_LONG__ * 8) 7#define __WORDSIZE (__SIZEOF_LONG__ * 8)
10#endif 8#endif
@@ -12,10 +10,9 @@
12#ifndef BITS_PER_LONG 10#ifndef BITS_PER_LONG
13# define BITS_PER_LONG __WORDSIZE 11# define BITS_PER_LONG __WORDSIZE
14#endif 12#endif
13#include <linux/bits.h>
14#include <linux/compiler.h>
15 15
16#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
17#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
18#define BITS_PER_BYTE 8
19#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) 16#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
20#define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64)) 17#define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64))
21#define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) 18#define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32))
diff --git a/tools/include/linux/bits.h b/tools/include/linux/bits.h
new file mode 100644
index 000000000000..2b7b532c1d51
--- /dev/null
+++ b/tools/include/linux/bits.h
@@ -0,0 +1,26 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __LINUX_BITS_H
3#define __LINUX_BITS_H
4#include <asm/bitsperlong.h>
5
6#define BIT(nr) (1UL << (nr))
7#define BIT_ULL(nr) (1ULL << (nr))
8#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
9#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
10#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG))
11#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG)
12#define BITS_PER_BYTE 8
13
14/*
15 * Create a contiguous bitmask starting at bit position @l and ending at
16 * position @h. For example
17 * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
18 */
19#define GENMASK(h, l) \
20 (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
21
22#define GENMASK_ULL(h, l) \
23 (((~0ULL) - (1ULL << (l)) + 1) & \
24 (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
25
26#endif /* __LINUX_BITS_H */
diff --git a/tools/lib/traceevent/Build b/tools/lib/traceevent/Build
index c681d0575d16..ba54bfce0b0b 100644
--- a/tools/lib/traceevent/Build
+++ b/tools/lib/traceevent/Build
@@ -4,6 +4,8 @@ libtraceevent-y += trace-seq.o
4libtraceevent-y += parse-filter.o 4libtraceevent-y += parse-filter.o
5libtraceevent-y += parse-utils.o 5libtraceevent-y += parse-utils.o
6libtraceevent-y += kbuffer-parse.o 6libtraceevent-y += kbuffer-parse.o
7libtraceevent-y += tep_strerror.o
8libtraceevent-y += event-parse-api.o
7 9
8plugin_jbd2-y += plugin_jbd2.o 10plugin_jbd2-y += plugin_jbd2.o
9plugin_hrtimer-y += plugin_hrtimer.o 11plugin_hrtimer-y += plugin_hrtimer.o
diff --git a/tools/lib/traceevent/event-parse-api.c b/tools/lib/traceevent/event-parse-api.c
new file mode 100644
index 000000000000..61f7149085ee
--- /dev/null
+++ b/tools/lib/traceevent/event-parse-api.c
@@ -0,0 +1,275 @@
1// SPDX-License-Identifier: LGPL-2.1
2/*
3 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
4 *
5 */
6
7#include "event-parse.h"
8#include "event-parse-local.h"
9#include "event-utils.h"
10
11/**
12 * tep_get_first_event - returns the first event in the events array
13 * @tep: a handle to the tep_handle
14 *
15 * This returns pointer to the first element of the events array
16 * If @tep is NULL, NULL is returned.
17 */
18struct tep_event_format *tep_get_first_event(struct tep_handle *tep)
19{
20 if (tep && tep->events)
21 return tep->events[0];
22
23 return NULL;
24}
25
26/**
27 * tep_get_events_count - get the number of defined events
28 * @tep: a handle to the tep_handle
29 *
30 * This returns number of elements in event array
31 * If @tep is NULL, 0 is returned.
32 */
33int tep_get_events_count(struct tep_handle *tep)
34{
35 if(tep)
36 return tep->nr_events;
37 return 0;
38}
39
40/**
41 * tep_set_flag - set event parser flag
42 * @tep: a handle to the tep_handle
43 * @flag: flag, or combination of flags to be set
44 * can be any combination from enum tep_flag
45 *
46 * This sets a flag or mbination of flags from enum tep_flag
47 */
48void tep_set_flag(struct tep_handle *tep, int flag)
49{
50 if(tep)
51 tep->flags |= flag;
52}
53
54unsigned short __tep_data2host2(struct tep_handle *pevent, unsigned short data)
55{
56 unsigned short swap;
57
58 if (!pevent || pevent->host_bigendian == pevent->file_bigendian)
59 return data;
60
61 swap = ((data & 0xffULL) << 8) |
62 ((data & (0xffULL << 8)) >> 8);
63
64 return swap;
65}
66
67unsigned int __tep_data2host4(struct tep_handle *pevent, unsigned int data)
68{
69 unsigned int swap;
70
71 if (!pevent || pevent->host_bigendian == pevent->file_bigendian)
72 return data;
73
74 swap = ((data & 0xffULL) << 24) |
75 ((data & (0xffULL << 8)) << 8) |
76 ((data & (0xffULL << 16)) >> 8) |
77 ((data & (0xffULL << 24)) >> 24);
78
79 return swap;
80}
81
82unsigned long long
83__tep_data2host8(struct tep_handle *pevent, unsigned long long data)
84{
85 unsigned long long swap;
86
87 if (!pevent || pevent->host_bigendian == pevent->file_bigendian)
88 return data;
89
90 swap = ((data & 0xffULL) << 56) |
91 ((data & (0xffULL << 8)) << 40) |
92 ((data & (0xffULL << 16)) << 24) |
93 ((data & (0xffULL << 24)) << 8) |
94 ((data & (0xffULL << 32)) >> 8) |
95 ((data & (0xffULL << 40)) >> 24) |
96 ((data & (0xffULL << 48)) >> 40) |
97 ((data & (0xffULL << 56)) >> 56);
98
99 return swap;
100}
101
102/**
103 * tep_get_header_page_size - get size of the header page
104 * @pevent: a handle to the tep_handle
105 *
106 * This returns size of the header page
107 * If @pevent is NULL, 0 is returned.
108 */
109int tep_get_header_page_size(struct tep_handle *pevent)
110{
111 if(pevent)
112 return pevent->header_page_size_size;
113 return 0;
114}
115
116/**
117 * tep_get_cpus - get the number of CPUs
118 * @pevent: a handle to the tep_handle
119 *
120 * This returns the number of CPUs
121 * If @pevent is NULL, 0 is returned.
122 */
123int tep_get_cpus(struct tep_handle *pevent)
124{
125 if(pevent)
126 return pevent->cpus;
127 return 0;
128}
129
130/**
131 * tep_set_cpus - set the number of CPUs
132 * @pevent: a handle to the tep_handle
133 *
134 * This sets the number of CPUs
135 */
136void tep_set_cpus(struct tep_handle *pevent, int cpus)
137{
138 if(pevent)
139 pevent->cpus = cpus;
140}
141
142/**
143 * tep_get_long_size - get the size of a long integer on the current machine
144 * @pevent: a handle to the tep_handle
145 *
146 * This returns the size of a long integer on the current machine
147 * If @pevent is NULL, 0 is returned.
148 */
149int tep_get_long_size(struct tep_handle *pevent)
150{
151 if(pevent)
152 return pevent->long_size;
153 return 0;
154}
155
156/**
157 * tep_set_long_size - set the size of a long integer on the current machine
158 * @pevent: a handle to the tep_handle
159 * @size: size, in bytes, of a long integer
160 *
161 * This sets the size of a long integer on the current machine
162 */
163void tep_set_long_size(struct tep_handle *pevent, int long_size)
164{
165 if(pevent)
166 pevent->long_size = long_size;
167}
168
169/**
170 * tep_get_page_size - get the size of a memory page on the current machine
171 * @pevent: a handle to the tep_handle
172 *
173 * This returns the size of a memory page on the current machine
174 * If @pevent is NULL, 0 is returned.
175 */
176int tep_get_page_size(struct tep_handle *pevent)
177{
178 if(pevent)
179 return pevent->page_size;
180 return 0;
181}
182
183/**
184 * tep_set_page_size - set the size of a memory page on the current machine
185 * @pevent: a handle to the tep_handle
186 * @_page_size: size of a memory page, in bytes
187 *
188 * This sets the size of a memory page on the current machine
189 */
190void tep_set_page_size(struct tep_handle *pevent, int _page_size)
191{
192 if(pevent)
193 pevent->page_size = _page_size;
194}
195
196/**
197 * tep_is_file_bigendian - get if the file is in big endian order
198 * @pevent: a handle to the tep_handle
199 *
200 * This returns if the file is in big endian order
201 * If @pevent is NULL, 0 is returned.
202 */
203int tep_is_file_bigendian(struct tep_handle *pevent)
204{
205 if(pevent)
206 return pevent->file_bigendian;
207 return 0;
208}
209
210/**
211 * tep_set_file_bigendian - set if the file is in big endian order
212 * @pevent: a handle to the tep_handle
213 * @endian: non zero, if the file is in big endian order
214 *
215 * This sets if the file is in big endian order
216 */
217void tep_set_file_bigendian(struct tep_handle *pevent, enum tep_endian endian)
218{
219 if(pevent)
220 pevent->file_bigendian = endian;
221}
222
223/**
224 * tep_is_host_bigendian - get if the order of the current host is big endian
225 * @pevent: a handle to the tep_handle
226 *
227 * This gets if the order of the current host is big endian
228 * If @pevent is NULL, 0 is returned.
229 */
230int tep_is_host_bigendian(struct tep_handle *pevent)
231{
232 if(pevent)
233 return pevent->host_bigendian;
234 return 0;
235}
236
237/**
238 * tep_set_host_bigendian - set the order of the local host
239 * @pevent: a handle to the tep_handle
240 * @endian: non zero, if the local host has big endian order
241 *
242 * This sets the order of the local host
243 */
244void tep_set_host_bigendian(struct tep_handle *pevent, enum tep_endian endian)
245{
246 if(pevent)
247 pevent->host_bigendian = endian;
248}
249
250/**
251 * tep_is_latency_format - get if the latency output format is configured
252 * @pevent: a handle to the tep_handle
253 *
254 * This gets if the latency output format is configured
255 * If @pevent is NULL, 0 is returned.
256 */
257int tep_is_latency_format(struct tep_handle *pevent)
258{
259 if(pevent)
260 return pevent->latency_format;
261 return 0;
262}
263
264/**
265 * tep_set_latency_format - set the latency output format
266 * @pevent: a handle to the tep_handle
267 * @lat: non zero for latency output format
268 *
269 * This sets the latency output format
270 */
271void tep_set_latency_format(struct tep_handle *pevent, int lat)
272{
273 if(pevent)
274 pevent->latency_format = lat;
275}
diff --git a/tools/lib/traceevent/event-parse-local.h b/tools/lib/traceevent/event-parse-local.h
new file mode 100644
index 000000000000..b9bddde577f8
--- /dev/null
+++ b/tools/lib/traceevent/event-parse-local.h
@@ -0,0 +1,92 @@
1// SPDX-License-Identifier: LGPL-2.1
2/*
3 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
4 *
5 */
6
7#ifndef _PARSE_EVENTS_INT_H
8#define _PARSE_EVENTS_INT_H
9
10struct cmdline;
11struct cmdline_list;
12struct func_map;
13struct func_list;
14struct event_handler;
15struct func_resolver;
16
17struct tep_handle {
18 int ref_count;
19
20 int header_page_ts_offset;
21 int header_page_ts_size;
22 int header_page_size_offset;
23 int header_page_size_size;
24 int header_page_data_offset;
25 int header_page_data_size;
26 int header_page_overwrite;
27
28 enum tep_endian file_bigendian;
29 enum tep_endian host_bigendian;
30
31 int latency_format;
32
33 int old_format;
34
35 int cpus;
36 int long_size;
37 int page_size;
38
39 struct cmdline *cmdlines;
40 struct cmdline_list *cmdlist;
41 int cmdline_count;
42
43 struct func_map *func_map;
44 struct func_resolver *func_resolver;
45 struct func_list *funclist;
46 unsigned int func_count;
47
48 struct printk_map *printk_map;
49 struct printk_list *printklist;
50 unsigned int printk_count;
51
52
53 struct tep_event_format **events;
54 int nr_events;
55 struct tep_event_format **sort_events;
56 enum tep_event_sort_type last_type;
57
58 int type_offset;
59 int type_size;
60
61 int pid_offset;
62 int pid_size;
63
64 int pc_offset;
65 int pc_size;
66
67 int flags_offset;
68 int flags_size;
69
70 int ld_offset;
71 int ld_size;
72
73 int print_raw;
74
75 int test_filters;
76
77 int flags;
78
79 struct tep_format_field *bprint_ip_field;
80 struct tep_format_field *bprint_fmt_field;
81 struct tep_format_field *bprint_buf_field;
82
83 struct event_handler *handlers;
84 struct tep_function_handler *func_handlers;
85
86 /* cache */
87 struct tep_event_format *last_event;
88
89 char *trace_clock;
90};
91
92#endif /* _PARSE_EVENTS_INT_H */
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 7980fc6c3bac..3692f29fee46 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -18,11 +18,12 @@
18#include <errno.h> 18#include <errno.h>
19#include <stdint.h> 19#include <stdint.h>
20#include <limits.h> 20#include <limits.h>
21#include <linux/string.h>
22#include <linux/time64.h> 21#include <linux/time64.h>
23 22
24#include <netinet/in.h> 23#include <netinet/in.h>
25#include "event-parse.h" 24#include "event-parse.h"
25
26#include "event-parse-local.h"
26#include "event-utils.h" 27#include "event-utils.h"
27#include "trace-seq.h" 28#include "trace-seq.h"
28 29
@@ -6201,35 +6202,6 @@ enum tep_errno tep_parse_event(struct tep_handle *pevent, const char *buf,
6201 return __parse_event(pevent, &event, buf, size, sys); 6202 return __parse_event(pevent, &event, buf, size, sys);
6202} 6203}
6203 6204
6204#undef _PE
6205#define _PE(code, str) str
6206static const char * const tep_error_str[] = {
6207 TEP_ERRORS
6208};
6209#undef _PE
6210
6211int tep_strerror(struct tep_handle *pevent __maybe_unused,
6212 enum tep_errno errnum, char *buf, size_t buflen)
6213{
6214 int idx;
6215 const char *msg;
6216
6217 if (errnum >= 0) {
6218 str_error_r(errnum, buf, buflen);
6219 return 0;
6220 }
6221
6222 if (errnum <= __TEP_ERRNO__START ||
6223 errnum >= __TEP_ERRNO__END)
6224 return -1;
6225
6226 idx = errnum - __TEP_ERRNO__START - 1;
6227 msg = tep_error_str[idx];
6228 snprintf(buf, buflen, "%s", msg);
6229
6230 return 0;
6231}
6232
6233int get_field_val(struct trace_seq *s, struct tep_format_field *field, 6205int get_field_val(struct trace_seq *s, struct tep_format_field *field,
6234 const char *name, struct tep_record *record, 6206 const char *name, struct tep_record *record,
6235 unsigned long long *val, int err) 6207 unsigned long long *val, int err)
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 9c29a5f7aa39..16bf4c890b6f 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -405,149 +405,18 @@ void tep_print_plugins(struct trace_seq *s,
405 const char *prefix, const char *suffix, 405 const char *prefix, const char *suffix,
406 const struct tep_plugin_list *list); 406 const struct tep_plugin_list *list);
407 407
408struct cmdline; 408/* tep_handle */
409struct cmdline_list;
410struct func_map;
411struct func_list;
412struct event_handler;
413struct func_resolver;
414
415typedef char *(tep_func_resolver_t)(void *priv, 409typedef char *(tep_func_resolver_t)(void *priv,
416 unsigned long long *addrp, char **modp); 410 unsigned long long *addrp, char **modp);
411void tep_set_flag(struct tep_handle *tep, int flag);
412unsigned short __tep_data2host2(struct tep_handle *pevent, unsigned short data);
413unsigned int __tep_data2host4(struct tep_handle *pevent, unsigned int data);
414unsigned long long
415__tep_data2host8(struct tep_handle *pevent, unsigned long long data);
417 416
418struct tep_handle { 417#define tep_data2host2(pevent, ptr) __tep_data2host2(pevent, *(unsigned short *)(ptr))
419 int ref_count; 418#define tep_data2host4(pevent, ptr) __tep_data2host4(pevent, *(unsigned int *)(ptr))
420 419#define tep_data2host8(pevent, ptr) \
421 int header_page_ts_offset;
422 int header_page_ts_size;
423 int header_page_size_offset;
424 int header_page_size_size;
425 int header_page_data_offset;
426 int header_page_data_size;
427 int header_page_overwrite;
428
429 int file_bigendian;
430 int host_bigendian;
431
432 int latency_format;
433
434 int old_format;
435
436 int cpus;
437 int long_size;
438 int page_size;
439
440 struct cmdline *cmdlines;
441 struct cmdline_list *cmdlist;
442 int cmdline_count;
443
444 struct func_map *func_map;
445 struct func_resolver *func_resolver;
446 struct func_list *funclist;
447 unsigned int func_count;
448
449 struct printk_map *printk_map;
450 struct printk_list *printklist;
451 unsigned int printk_count;
452
453
454 struct tep_event_format **events;
455 int nr_events;
456 struct tep_event_format **sort_events;
457 enum tep_event_sort_type last_type;
458
459 int type_offset;
460 int type_size;
461
462 int pid_offset;
463 int pid_size;
464
465 int pc_offset;
466 int pc_size;
467
468 int flags_offset;
469 int flags_size;
470
471 int ld_offset;
472 int ld_size;
473
474 int print_raw;
475
476 int test_filters;
477
478 int flags;
479
480 struct tep_format_field *bprint_ip_field;
481 struct tep_format_field *bprint_fmt_field;
482 struct tep_format_field *bprint_buf_field;
483
484 struct event_handler *handlers;
485 struct tep_function_handler *func_handlers;
486
487 /* cache */
488 struct tep_event_format *last_event;
489
490 char *trace_clock;
491};
492
493static inline void tep_set_flag(struct tep_handle *pevent, int flag)
494{
495 pevent->flags |= flag;
496}
497
498static inline unsigned short
499__tep_data2host2(struct tep_handle *pevent, unsigned short data)
500{
501 unsigned short swap;
502
503 if (pevent->host_bigendian == pevent->file_bigendian)
504 return data;
505
506 swap = ((data & 0xffULL) << 8) |
507 ((data & (0xffULL << 8)) >> 8);
508
509 return swap;
510}
511
512static inline unsigned int
513__tep_data2host4(struct tep_handle *pevent, unsigned int data)
514{
515 unsigned int swap;
516
517 if (pevent->host_bigendian == pevent->file_bigendian)
518 return data;
519
520 swap = ((data & 0xffULL) << 24) |
521 ((data & (0xffULL << 8)) << 8) |
522 ((data & (0xffULL << 16)) >> 8) |
523 ((data & (0xffULL << 24)) >> 24);
524
525 return swap;
526}
527
528static inline unsigned long long
529__tep_data2host8(struct tep_handle *pevent, unsigned long long data)
530{
531 unsigned long long swap;
532
533 if (pevent->host_bigendian == pevent->file_bigendian)
534 return data;
535
536 swap = ((data & 0xffULL) << 56) |
537 ((data & (0xffULL << 8)) << 40) |
538 ((data & (0xffULL << 16)) << 24) |
539 ((data & (0xffULL << 24)) << 8) |
540 ((data & (0xffULL << 32)) >> 8) |
541 ((data & (0xffULL << 40)) >> 24) |
542 ((data & (0xffULL << 48)) >> 40) |
543 ((data & (0xffULL << 56)) >> 56);
544
545 return swap;
546}
547
548#define tep_data2host2(pevent, ptr) __tep_data2host2(pevent, *(unsigned short *)(ptr))
549#define tep_data2host4(pevent, ptr) __tep_data2host4(pevent, *(unsigned int *)(ptr))
550#define tep_data2host8(pevent, ptr) \
551({ \ 420({ \
552 unsigned long long __val; \ 421 unsigned long long __val; \
553 \ 422 \
@@ -655,11 +524,12 @@ unsigned long long tep_read_number(struct tep_handle *pevent, const void *ptr, i
655int tep_read_number_field(struct tep_format_field *field, const void *data, 524int tep_read_number_field(struct tep_format_field *field, const void *data,
656 unsigned long long *value); 525 unsigned long long *value);
657 526
527struct tep_event_format *tep_get_first_event(struct tep_handle *tep);
528int tep_get_events_count(struct tep_handle *tep);
658struct tep_event_format *tep_find_event(struct tep_handle *pevent, int id); 529struct tep_event_format *tep_find_event(struct tep_handle *pevent, int id);
659 530
660struct tep_event_format * 531struct tep_event_format *
661tep_find_event_by_name(struct tep_handle *pevent, const char *sys, const char *name); 532tep_find_event_by_name(struct tep_handle *pevent, const char *sys, const char *name);
662
663struct tep_event_format * 533struct tep_event_format *
664tep_find_event_by_record(struct tep_handle *pevent, struct tep_record *record); 534tep_find_event_by_record(struct tep_handle *pevent, struct tep_record *record);
665 535
@@ -689,65 +559,23 @@ struct tep_event_format **tep_list_events(struct tep_handle *pevent, enum tep_ev
689struct tep_format_field **tep_event_common_fields(struct tep_event_format *event); 559struct tep_format_field **tep_event_common_fields(struct tep_event_format *event);
690struct tep_format_field **tep_event_fields(struct tep_event_format *event); 560struct tep_format_field **tep_event_fields(struct tep_event_format *event);
691 561
692static inline int tep_get_cpus(struct tep_handle *pevent) 562enum tep_endian {
693{ 563 TEP_LITTLE_ENDIAN = 0,
694 return pevent->cpus; 564 TEP_BIG_ENDIAN
695} 565};
696 566int tep_get_cpus(struct tep_handle *pevent);
697static inline void tep_set_cpus(struct tep_handle *pevent, int cpus) 567void tep_set_cpus(struct tep_handle *pevent, int cpus);
698{ 568int tep_get_long_size(struct tep_handle *pevent);
699 pevent->cpus = cpus; 569void tep_set_long_size(struct tep_handle *pevent, int long_size);
700} 570int tep_get_page_size(struct tep_handle *pevent);
701 571void tep_set_page_size(struct tep_handle *pevent, int _page_size);
702static inline int tep_get_long_size(struct tep_handle *pevent) 572int tep_is_file_bigendian(struct tep_handle *pevent);
703{ 573void tep_set_file_bigendian(struct tep_handle *pevent, enum tep_endian endian);
704 return pevent->long_size; 574int tep_is_host_bigendian(struct tep_handle *pevent);
705} 575void tep_set_host_bigendian(struct tep_handle *pevent, enum tep_endian endian);
706 576int tep_is_latency_format(struct tep_handle *pevent);
707static inline void tep_set_long_size(struct tep_handle *pevent, int long_size) 577void tep_set_latency_format(struct tep_handle *pevent, int lat);
708{ 578int tep_get_header_page_size(struct tep_handle *pevent);
709 pevent->long_size = long_size;
710}
711
712static inline int tep_get_page_size(struct tep_handle *pevent)
713{
714 return pevent->page_size;
715}
716
717static inline void tep_set_page_size(struct tep_handle *pevent, int _page_size)
718{
719 pevent->page_size = _page_size;
720}
721
722static inline int tep_is_file_bigendian(struct tep_handle *pevent)
723{
724 return pevent->file_bigendian;
725}
726
727static inline void tep_set_file_bigendian(struct tep_handle *pevent, int endian)
728{
729 pevent->file_bigendian = endian;
730}
731
732static inline int tep_is_host_bigendian(struct tep_handle *pevent)
733{
734 return pevent->host_bigendian;
735}
736
737static inline void tep_set_host_bigendian(struct tep_handle *pevent, int endian)
738{
739 pevent->host_bigendian = endian;
740}
741
742static inline int tep_is_latency_format(struct tep_handle *pevent)
743{
744 return pevent->latency_format;
745}
746
747static inline void tep_set_latency_format(struct tep_handle *pevent, int lat)
748{
749 pevent->latency_format = lat;
750}
751 579
752struct tep_handle *tep_alloc(void); 580struct tep_handle *tep_alloc(void);
753void tep_free(struct tep_handle *pevent); 581void tep_free(struct tep_handle *pevent);
diff --git a/tools/lib/traceevent/event-plugin.c b/tools/lib/traceevent/event-plugin.c
index 46eb64eb0c2e..e74f16c88398 100644
--- a/tools/lib/traceevent/event-plugin.c
+++ b/tools/lib/traceevent/event-plugin.c
@@ -14,6 +14,7 @@
14#include <unistd.h> 14#include <unistd.h>
15#include <dirent.h> 15#include <dirent.h>
16#include "event-parse.h" 16#include "event-parse.h"
17#include "event-parse-local.h"
17#include "event-utils.h" 18#include "event-utils.h"
18#include "trace-seq.h" 19#include "trace-seq.h"
19 20
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index d64b6128fa7d..ed87cb56713d 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -11,6 +11,7 @@
11#include <sys/types.h> 11#include <sys/types.h>
12 12
13#include "event-parse.h" 13#include "event-parse.h"
14#include "event-parse-local.h"
14#include "event-utils.h" 15#include "event-utils.h"
15 16
16#define COMM "COMM" 17#define COMM "COMM"
diff --git a/tools/lib/traceevent/tep_strerror.c b/tools/lib/traceevent/tep_strerror.c
new file mode 100644
index 000000000000..4ac26445b2f6
--- /dev/null
+++ b/tools/lib/traceevent/tep_strerror.c
@@ -0,0 +1,53 @@
1// SPDX-License-Identifier: LGPL-2.1
2#undef _GNU_SOURCE
3#include <string.h>
4#include <stdio.h>
5
6#include "event-parse.h"
7
8#undef _PE
9#define _PE(code, str) str
10static const char * const tep_error_str[] = {
11 TEP_ERRORS
12};
13#undef _PE
14
15/*
16 * The tools so far have been using the strerror_r() GNU variant, that returns
17 * a string, be it the buffer passed or something else.
18 *
19 * But that, besides being tricky in cases where we expect that the function
20 * using strerror_r() returns the error formatted in a provided buffer (we have
21 * to check if it returned something else and copy that instead), breaks the
22 * build on systems not using glibc, like Alpine Linux, where musl libc is
23 * used.
24 *
25 * So, introduce yet another wrapper, str_error_r(), that has the GNU
26 * interface, but uses the portable XSI variant of strerror_r(), so that users
27 * rest asured that the provided buffer is used and it is what is returned.
28 */
29int tep_strerror(struct tep_handle *tep __maybe_unused,
30 enum tep_errno errnum, char *buf, size_t buflen)
31{
32 const char *msg;
33 int idx;
34
35 if (!buflen)
36 return 0;
37
38 if (errnum >= 0) {
39 int err = strerror_r(errnum, buf, buflen);
40 buf[buflen - 1] = 0;
41 return err;
42 }
43
44 if (errnum <= __TEP_ERRNO__START ||
45 errnum >= __TEP_ERRNO__END)
46 return -1;
47
48 idx = errnum - __TEP_ERRNO__START - 1;
49 msg = tep_error_str[idx];
50 snprintf(buf, buflen, "%s", msg);
51
52 return 0;
53}
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 466540ee8ea7..c72cc73a6b09 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -14,6 +14,7 @@ include/uapi/linux/sched.h
14include/uapi/linux/stat.h 14include/uapi/linux/stat.h
15include/uapi/linux/vhost.h 15include/uapi/linux/vhost.h
16include/uapi/sound/asound.h 16include/uapi/sound/asound.h
17include/linux/bits.h
17include/linux/hash.h 18include/linux/hash.h
18include/uapi/linux/hw_breakpoint.h 19include/uapi/linux/hw_breakpoint.h
19arch/x86/include/asm/disabled-features.h 20arch/x86/include/asm/disabled-features.h
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 54ca7d87236f..12c09e0ece71 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -123,6 +123,7 @@ static struct test generic_tests[] = {
123 { 123 {
124 .desc = "Watchpoint", 124 .desc = "Watchpoint",
125 .func = test__wp, 125 .func = test__wp,
126 .is_supported = test__wp_is_supported,
126 .subtest = { 127 .subtest = {
127 .skip_if_fail = false, 128 .skip_if_fail = false,
128 .get_nr = test__wp_subtest_get_nr, 129 .get_nr = test__wp_subtest_get_nr,
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 8e26a4148f30..b82f55fcc294 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -109,6 +109,7 @@ int test__unit_number__scnprint(struct test *test, int subtest);
109int test__mem2node(struct test *t, int subtest); 109int test__mem2node(struct test *t, int subtest);
110 110
111bool test__bp_signal_is_supported(void); 111bool test__bp_signal_is_supported(void);
112bool test__wp_is_supported(void);
112 113
113#if defined(__arm__) || defined(__aarch64__) 114#if defined(__arm__) || defined(__aarch64__)
114#ifdef HAVE_DWARF_UNWIND_SUPPORT 115#ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/tests/wp.c b/tools/perf/tests/wp.c
index 017a99317f94..f89e6806557b 100644
--- a/tools/perf/tests/wp.c
+++ b/tools/perf/tests/wp.c
@@ -227,3 +227,15 @@ int test__wp(struct test *test __maybe_unused, int i)
227 227
228 return !wp_testcase_table[i].target_func() ? TEST_OK : TEST_FAIL; 228 return !wp_testcase_table[i].target_func() ? TEST_OK : TEST_FAIL;
229} 229}
230
231/* The s390 so far does not have support for
232 * instruction breakpoint using the perf_event_open() system call.
233 */
234bool test__wp_is_supported(void)
235{
236#if defined(__s390x__)
237 return false;
238#else
239 return true;
240#endif
241}
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index 0a6ce9c4fc11..d88f6e9eb461 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -23,6 +23,7 @@
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/perf_event.h> 24#include <linux/perf_event.h>
25#include <linux/types.h> 25#include <linux/types.h>
26#include <asm/bitsperlong.h>
26 27
27#include "../perf.h" 28#include "../perf.h"
28#include "event.h" 29#include "event.h"
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index 1942f6dd24f6..63f758c655d5 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -5,16 +5,18 @@ from subprocess import Popen, PIPE
5from re import sub 5from re import sub
6 6
7def clang_has_option(option): 7def clang_has_option(option):
8 return [o for o in Popen(['clang', option], stderr=PIPE).stderr.readlines() if "unknown argument" in o] == [ ] 8 return [o for o in Popen(['clang', option], stderr=PIPE).stderr.readlines() if b"unknown argument" in o] == [ ]
9 9
10cc = getenv("CC") 10cc = getenv("CC")
11if cc == "clang": 11if cc == "clang":
12 from _sysconfigdata import build_time_vars 12 from distutils.sysconfig import get_config_vars
13 build_time_vars["CFLAGS"] = sub("-specs=[^ ]+", "", build_time_vars["CFLAGS"]) 13 vars = get_config_vars()
14 if not clang_has_option("-mcet"): 14 for var in ('CFLAGS', 'OPT'):
15 build_time_vars["CFLAGS"] = sub("-mcet", "", build_time_vars["CFLAGS"]) 15 vars[var] = sub("-specs=[^ ]+", "", vars[var])
16 if not clang_has_option("-fcf-protection"): 16 if not clang_has_option("-mcet"):
17 build_time_vars["CFLAGS"] = sub("-fcf-protection", "", build_time_vars["CFLAGS"]) 17 vars[var] = sub("-mcet", "", vars[var])
18 if not clang_has_option("-fcf-protection"):
19 vars[var] = sub("-fcf-protection", "", vars[var])
18 20
19from distutils.core import setup, Extension 21from distutils.core import setup, Extension
20 22
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
index 3d1cf5bf7f18..9005fbe0780e 100644
--- a/tools/perf/util/strbuf.c
+++ b/tools/perf/util/strbuf.c
@@ -98,19 +98,25 @@ static int strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
98 98
99 va_copy(ap_saved, ap); 99 va_copy(ap_saved, ap);
100 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); 100 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
101 if (len < 0) 101 if (len < 0) {
102 va_end(ap_saved);
102 return len; 103 return len;
104 }
103 if (len > strbuf_avail(sb)) { 105 if (len > strbuf_avail(sb)) {
104 ret = strbuf_grow(sb, len); 106 ret = strbuf_grow(sb, len);
105 if (ret) 107 if (ret) {
108 va_end(ap_saved);
106 return ret; 109 return ret;
110 }
107 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved); 111 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved);
108 va_end(ap_saved); 112 va_end(ap_saved);
109 if (len > strbuf_avail(sb)) { 113 if (len > strbuf_avail(sb)) {
110 pr_debug("this should not happen, your vsnprintf is broken"); 114 pr_debug("this should not happen, your vsnprintf is broken");
115 va_end(ap_saved);
111 return -EINVAL; 116 return -EINVAL;
112 } 117 }
113 } 118 }
119 va_end(ap_saved);
114 return strbuf_setlen(sb, sb->len + len); 120 return strbuf_setlen(sb, sb->len + len);
115} 121}
116 122
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 7b0ca7cbb7de..8ad8e755127b 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -531,12 +531,14 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
531 "/tmp/perf-XXXXXX"); 531 "/tmp/perf-XXXXXX");
532 if (!mkstemp(tdata->temp_file)) { 532 if (!mkstemp(tdata->temp_file)) {
533 pr_debug("Can't make temp file"); 533 pr_debug("Can't make temp file");
534 free(tdata);
534 return NULL; 535 return NULL;
535 } 536 }
536 537
537 temp_fd = open(tdata->temp_file, O_RDWR); 538 temp_fd = open(tdata->temp_file, O_RDWR);
538 if (temp_fd < 0) { 539 if (temp_fd < 0) {
539 pr_debug("Can't read '%s'", tdata->temp_file); 540 pr_debug("Can't read '%s'", tdata->temp_file);
541 free(tdata);
540 return NULL; 542 return NULL;
541 } 543 }
542 544
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index a4d7de1c96d1..32e558a65af3 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -37,10 +37,11 @@ static int get_common_field(struct scripting_context *context,
37 struct tep_format_field *field; 37 struct tep_format_field *field;
38 38
39 if (!*size) { 39 if (!*size) {
40 if (!pevent->events) 40
41 event = tep_get_first_event(pevent);
42 if (!event)
41 return 0; 43 return 0;
42 44
43 event = pevent->events[0];
44 field = tep_find_common_field(event, type); 45 field = tep_find_common_field(event, type);
45 if (!field) 46 if (!field)
46 return 0; 47 return 0;
@@ -158,6 +159,7 @@ void parse_ftrace_printk(struct tep_handle *pevent,
158 printk = strdup(fmt+1); 159 printk = strdup(fmt+1);
159 line = strtok_r(NULL, "\n", &next); 160 line = strtok_r(NULL, "\n", &next);
160 tep_register_print_string(pevent, printk, addr); 161 tep_register_print_string(pevent, printk, addr);
162 free(printk);
161 } 163 }
162} 164}
163 165
@@ -192,25 +194,29 @@ struct tep_event_format *trace_find_next_event(struct tep_handle *pevent,
192 struct tep_event_format *event) 194 struct tep_event_format *event)
193{ 195{
194 static int idx; 196 static int idx;
197 int events_count;
198 struct tep_event_format *all_events;
195 199
196 if (!pevent || !pevent->events) 200 all_events = tep_get_first_event(pevent);
201 events_count = tep_get_events_count(pevent);
202 if (!pevent || !all_events || events_count < 1)
197 return NULL; 203 return NULL;
198 204
199 if (!event) { 205 if (!event) {
200 idx = 0; 206 idx = 0;
201 return pevent->events[0]; 207 return all_events;
202 } 208 }
203 209
204 if (idx < pevent->nr_events && event == pevent->events[idx]) { 210 if (idx < events_count && event == (all_events + idx)) {
205 idx++; 211 idx++;
206 if (idx == pevent->nr_events) 212 if (idx == events_count)
207 return NULL; 213 return NULL;
208 return pevent->events[idx]; 214 return (all_events + idx);
209 } 215 }
210 216
211 for (idx = 1; idx < pevent->nr_events; idx++) { 217 for (idx = 1; idx < events_count; idx++) {
212 if (event == pevent->events[idx - 1]) 218 if (event == (all_events + (idx - 1)))
213 return pevent->events[idx]; 219 return (all_events + idx);
214 } 220 }
215 return NULL; 221 return NULL;
216} 222}
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index b98ee2a2eb44..76f12c705ef9 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -241,7 +241,7 @@ static int read_header_files(struct tep_handle *pevent)
241 * The commit field in the page is of type long, 241 * The commit field in the page is of type long,
242 * use that instead, since it represents the kernel. 242 * use that instead, since it represents the kernel.
243 */ 243 */
244 tep_set_long_size(pevent, pevent->header_page_size_size); 244 tep_set_long_size(pevent, tep_get_header_page_size(pevent));
245 } 245 }
246 free(header_page); 246 free(header_page);
247 247
@@ -297,10 +297,8 @@ static int read_event_file(struct tep_handle *pevent, char *sys,
297 } 297 }
298 298
299 ret = do_read(buf, size); 299 ret = do_read(buf, size);
300 if (ret < 0) { 300 if (ret < 0)
301 free(buf);
302 goto out; 301 goto out;
303 }
304 302
305 ret = parse_event_file(pevent, buf, size, sys); 303 ret = parse_event_file(pevent, buf, size, sys);
306 if (ret < 0) 304 if (ret < 0)
@@ -349,9 +347,12 @@ static int read_event_files(struct tep_handle *pevent)
349 for (x=0; x < count; x++) { 347 for (x=0; x < count; x++) {
350 size = read8(pevent); 348 size = read8(pevent);
351 ret = read_event_file(pevent, sys, size); 349 ret = read_event_file(pevent, sys, size);
352 if (ret) 350 if (ret) {
351 free(sys);
353 return ret; 352 return ret;
353 }
354 } 354 }
355 free(sys);
355 } 356 }
356 return 0; 357 return 0;
357} 358}