Blame view

tools/perf/builtin-inject.c 25.1 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
454c407ec   Tom Zanussi   perf: add perf-in...
2
3
4
5
6
7
8
9
  /*
   * builtin-inject.c
   *
   * Builtin inject command: Examine the live mode (stdin) event stream
   * and repipe it to stdout while optionally injecting additional
   * events into it.
   */
  #include "builtin.h"
26a031e13   Andrew Vagin   perf inject: Merg...
10
  #include "util/color.h"
4a3cec849   Arnaldo Carvalho de Melo   perf dsos: Move t...
11
  #include "util/dso.h"
27c9c3424   Namhyung Kim   perf inject: Add ...
12
  #include "util/vdso.h"
26a031e13   Andrew Vagin   perf inject: Merg...
13
14
  #include "util/evlist.h"
  #include "util/evsel.h"
1101f69af   Arnaldo Carvalho de Melo   pref tools: Add m...
15
  #include "util/map.h"
454c407ec   Tom Zanussi   perf: add perf-in...
16
  #include "util/session.h"
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
17
  #include "util/tool.h"
454c407ec   Tom Zanussi   perf: add perf-in...
18
  #include "util/debug.h"
54a3cf59b   Andrew Vagin   perf inject: Mark...
19
  #include "util/build-id.h"
f5fc14124   Jiri Olsa   perf tools: Add d...
20
  #include "util/data.h"
0f0aa5e06   Adrian Hunter   perf inject: Add ...
21
  #include "util/auxtrace.h"
9b07e27f8   Stephane Eranian   perf inject: Add ...
22
  #include "util/jit.h"
daecf9e0f   Arnaldo Carvalho de Melo   perf tools: Add m...
23
  #include "util/symbol.h"
ea49e01cf   Arnaldo Carvalho de Melo   perf tools: Move ...
24
  #include "util/synthetic-events.h"
e7ff8920e   Arnaldo Carvalho de Melo   perf tools: Use j...
25
  #include "util/thread.h"
336c95b29   Namhyung Kim   perf inject: Ente...
26
  #include "util/namespaces.h"
454c407ec   Tom Zanussi   perf: add perf-in...
27

e7b60c5a0   Namhyung Kim   perf inject: Do n...
28
  #include <linux/err.h>
4b6ab94ea   Josh Poimboeuf   perf subcmd: Crea...
29
  #include <subcmd/parse-options.h>
e7b60c5a0   Namhyung Kim   perf inject: Do n...
30
  #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
454c407ec   Tom Zanussi   perf: add perf-in...
31

26a031e13   Andrew Vagin   perf inject: Merg...
32
  #include <linux/list.h>
a43783aee   Arnaldo Carvalho de Melo   perf tools: Inclu...
33
  #include <errno.h>
9607ad3a6   Arnaldo Carvalho de Melo   perf tools: Add s...
34
  #include <signal.h>
26a031e13   Andrew Vagin   perf inject: Merg...
35

5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
36
  struct perf_inject {
3406912cc   Jiri Olsa   perf inject: Hand...
37
  	struct perf_tool	tool;
1cb8bdcca   Namhyung Kim   perf inject: Move...
38
  	struct perf_session	*session;
3406912cc   Jiri Olsa   perf inject: Hand...
39
  	bool			build_ids;
27c9c3424   Namhyung Kim   perf inject: Add ...
40
  	bool			build_id_all;
3406912cc   Jiri Olsa   perf inject: Hand...
41
  	bool			sched_stat;
cd10b2895   Adrian Hunter   perf tools: Hit a...
42
  	bool			have_auxtrace;
f56fb9864   Adrian Hunter   perf inject: Add ...
43
  	bool			strip;
9b07e27f8   Stephane Eranian   perf inject: Add ...
44
  	bool			jit_mode;
3406912cc   Jiri Olsa   perf inject: Hand...
45
  	const char		*input_name;
8ceb41d7e   Jiri Olsa   perf tools: Renam...
46
  	struct perf_data	output;
3406912cc   Jiri Olsa   perf inject: Hand...
47
  	u64			bytes_written;
73117308f   Adrian Hunter   perf inject: Remo...
48
  	u64			aux_id;
3406912cc   Jiri Olsa   perf inject: Hand...
49
  	struct list_head	samples;
0f0aa5e06   Adrian Hunter   perf inject: Add ...
50
  	struct itrace_synth_opts itrace_synth_opts;
ba2675bf1   Adrian Hunter   perf inject: Cut ...
51
  	char			event_copy[PERF_SAMPLE_MAX_SIZE];
26a031e13   Andrew Vagin   perf inject: Merg...
52
53
54
55
56
  };
  
  struct event_entry {
  	struct list_head node;
  	u32		 tid;
6549a8c0c   Gustavo A. R. Silva   perf tools: Repla...
57
  	union perf_event event[];
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
58
  };
454c407ec   Tom Zanussi   perf: add perf-in...
59

27c9c3424   Namhyung Kim   perf inject: Add ...
60
61
  static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
  				struct machine *machine, u8 cpumode, u32 flags);
cd17a9b54   Adrian Hunter   perf inject: Re-p...
62
  static int output_bytes(struct perf_inject *inject, void *buf, size_t sz)
454c407ec   Tom Zanussi   perf: add perf-in...
63
  {
3406912cc   Jiri Olsa   perf inject: Hand...
64
  	ssize_t size;
454c407ec   Tom Zanussi   perf: add perf-in...
65

8ceb41d7e   Jiri Olsa   perf tools: Renam...
66
  	size = perf_data__write(&inject->output, buf, sz);
3406912cc   Jiri Olsa   perf inject: Hand...
67
68
  	if (size < 0)
  		return -errno;
454c407ec   Tom Zanussi   perf: add perf-in...
69

3406912cc   Jiri Olsa   perf inject: Hand...
70
  	inject->bytes_written += size;
454c407ec   Tom Zanussi   perf: add perf-in...
71
72
  	return 0;
  }
cd17a9b54   Adrian Hunter   perf inject: Re-p...
73
74
75
76
77
78
79
80
  static int perf_event__repipe_synth(struct perf_tool *tool,
  				    union perf_event *event)
  {
  	struct perf_inject *inject = container_of(tool, struct perf_inject,
  						  tool);
  
  	return output_bytes(inject, event, event->header.size);
  }
d704ebdae   Arnaldo Carvalho de Melo   perf tools: tool-...
81
82
83
84
85
86
  static int perf_event__repipe_oe_synth(struct perf_tool *tool,
  				       union perf_event *event,
  				       struct ordered_events *oe __maybe_unused)
  {
  	return perf_event__repipe_synth(tool, event);
  }
e12b202f8   Jiri Olsa   perf jitdump: Bui...
87
  #ifdef HAVE_JITDUMP
9b07e27f8   Stephane Eranian   perf inject: Add ...
88
89
90
91
92
93
94
  static int perf_event__drop_oe(struct perf_tool *tool __maybe_unused,
  			       union perf_event *event __maybe_unused,
  			       struct ordered_events *oe __maybe_unused)
  {
  	return 0;
  }
  #endif
89f1688a5   Jiri Olsa   perf tools: Remov...
95
96
  static int perf_event__repipe_op2_synth(struct perf_session *session,
  					union perf_event *event)
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
97
  {
89f1688a5   Jiri Olsa   perf tools: Remov...
98
  	return perf_event__repipe_synth(session->tool, event);
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
99
  }
2946ecedd   Namhyung Kim   perf inject: Add ...
100
101
102
103
104
105
  static int perf_event__repipe_op4_synth(struct perf_session *session,
  					union perf_event *event,
  					u64 data __maybe_unused)
  {
  	return perf_event__repipe_synth(session->tool, event);
  }
47c3d1091   Adrian Hunter   perf tools: Fix m...
106
107
  static int perf_event__repipe_attr(struct perf_tool *tool,
  				   union perf_event *event,
63503dba8   Jiri Olsa   perf evlist: Rena...
108
  				   struct evlist **pevlist)
10d0f086d   Arnaldo Carvalho de Melo   perf event: perf_...
109
  {
89c97d936   Adrian Hunter   perf inject: Do n...
110
111
  	struct perf_inject *inject = container_of(tool, struct perf_inject,
  						  tool);
1a1ed1ba6   Stephane Eranian   perf inject: Fix ...
112
  	int ret;
47c3d1091   Adrian Hunter   perf tools: Fix m...
113
114
  
  	ret = perf_event__process_attr(tool, event, pevlist);
1a1ed1ba6   Stephane Eranian   perf inject: Fix ...
115
116
  	if (ret)
  		return ret;
a261e4a09   Jiri Olsa   perf tools: Fix p...
117
  	if (!inject->output.is_pipe)
89c97d936   Adrian Hunter   perf inject: Do n...
118
  		return 0;
47c3d1091   Adrian Hunter   perf tools: Fix m...
119
  	return perf_event__repipe_synth(tool, event);
10d0f086d   Arnaldo Carvalho de Melo   perf event: perf_...
120
  }
2946ecedd   Namhyung Kim   perf inject: Add ...
121
122
123
124
125
126
  static int perf_event__repipe_event_update(struct perf_tool *tool,
  					   union perf_event *event,
  					   struct evlist **pevlist __maybe_unused)
  {
  	return perf_event__repipe_synth(tool, event);
  }
e31f0d017   Adrian Hunter   perf tools: Add b...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  #ifdef HAVE_AUXTRACE_SUPPORT
  
  static int copy_bytes(struct perf_inject *inject, int fd, off_t size)
  {
  	char buf[4096];
  	ssize_t ssz;
  	int ret;
  
  	while (size > 0) {
  		ssz = read(fd, buf, min(size, (off_t)sizeof(buf)));
  		if (ssz < 0)
  			return -errno;
  		ret = output_bytes(inject, buf, ssz);
  		if (ret)
  			return ret;
  		size -= ssz;
  	}
  
  	return 0;
  }
7336555a6   Jiri Olsa   perf tools: Remov...
147
148
  static s64 perf_event__repipe_auxtrace(struct perf_session *session,
  				       union perf_event *event)
cd17a9b54   Adrian Hunter   perf inject: Re-p...
149
  {
7336555a6   Jiri Olsa   perf tools: Remov...
150
  	struct perf_tool *tool = session->tool;
cd17a9b54   Adrian Hunter   perf inject: Re-p...
151
152
153
  	struct perf_inject *inject = container_of(tool, struct perf_inject,
  						  tool);
  	int ret;
cd10b2895   Adrian Hunter   perf tools: Hit a...
154
  	inject->have_auxtrace = true;
99fa29845   Adrian Hunter   perf tools: Add A...
155
156
  	if (!inject->output.is_pipe) {
  		off_t offset;
eae8ad804   Jiri Olsa   perf tools: Add s...
157
  		offset = lseek(inject->output.file.fd, 0, SEEK_CUR);
99fa29845   Adrian Hunter   perf tools: Add A...
158
159
160
161
162
163
164
  		if (offset == -1)
  			return -errno;
  		ret = auxtrace_index__auxtrace_event(&session->auxtrace_index,
  						     event, offset);
  		if (ret < 0)
  			return ret;
  	}
8ceb41d7e   Jiri Olsa   perf tools: Renam...
165
  	if (perf_data__is_pipe(session->data) || !session->one_mmap) {
cd17a9b54   Adrian Hunter   perf inject: Re-p...
166
167
168
  		ret = output_bytes(inject, event, event->header.size);
  		if (ret < 0)
  			return ret;
8ceb41d7e   Jiri Olsa   perf tools: Renam...
169
  		ret = copy_bytes(inject, perf_data__fd(session->data),
cd17a9b54   Adrian Hunter   perf inject: Re-p...
170
171
172
173
174
175
176
177
178
179
  				 event->auxtrace.size);
  	} else {
  		ret = output_bytes(inject, event,
  				   event->header.size + event->auxtrace.size);
  	}
  	if (ret < 0)
  		return ret;
  
  	return event->auxtrace.size;
  }
e31f0d017   Adrian Hunter   perf tools: Add b...
180
181
182
  #else
  
  static s64
7336555a6   Jiri Olsa   perf tools: Remov...
183
184
  perf_event__repipe_auxtrace(struct perf_session *session __maybe_unused,
  			    union perf_event *event __maybe_unused)
e31f0d017   Adrian Hunter   perf tools: Add b...
185
186
187
188
189
190
191
  {
  	pr_err("AUX area tracing not supported
  ");
  	return -EINVAL;
  }
  
  #endif
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
192
  static int perf_event__repipe(struct perf_tool *tool,
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
193
  			      union perf_event *event,
1d037ca16   Irina Tirdea   perf tools: Use _...
194
  			      struct perf_sample *sample __maybe_unused,
63c2c9f8f   Adrian Hunter   perf inject: Remo...
195
  			      struct machine *machine __maybe_unused)
640c03ce8   Arnaldo Carvalho de Melo   perf session: Par...
196
  {
63c2c9f8f   Adrian Hunter   perf inject: Remo...
197
  	return perf_event__repipe_synth(tool, event);
640c03ce8   Arnaldo Carvalho de Melo   perf session: Par...
198
  }
f56fb9864   Adrian Hunter   perf inject: Add ...
199
200
201
202
203
204
205
  static int perf_event__drop(struct perf_tool *tool __maybe_unused,
  			    union perf_event *event __maybe_unused,
  			    struct perf_sample *sample __maybe_unused,
  			    struct machine *machine __maybe_unused)
  {
  	return 0;
  }
73117308f   Adrian Hunter   perf inject: Remo...
206
207
208
209
210
211
212
213
214
215
216
217
  static int perf_event__drop_aux(struct perf_tool *tool,
  				union perf_event *event __maybe_unused,
  				struct perf_sample *sample,
  				struct machine *machine __maybe_unused)
  {
  	struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  
  	if (!inject->aux_id)
  		inject->aux_id = sample->id;
  
  	return 0;
  }
ba2675bf1   Adrian Hunter   perf inject: Cut ...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
  static union perf_event *
  perf_inject__cut_auxtrace_sample(struct perf_inject *inject,
  				 union perf_event *event,
  				 struct perf_sample *sample)
  {
  	size_t sz1 = sample->aux_sample.data - (void *)event;
  	size_t sz2 = event->header.size - sample->aux_sample.size - sz1;
  	union perf_event *ev = (union perf_event *)inject->event_copy;
  
  	if (sz1 > event->header.size || sz2 > event->header.size ||
  	    sz1 + sz2 > event->header.size ||
  	    sz1 < sizeof(struct perf_event_header) + sizeof(u64))
  		return event;
  
  	memcpy(ev, event, sz1);
  	memcpy((void *)ev + sz1, (void *)event + event->header.size - sz2, sz2);
  	ev->header.size = sz1 + sz2;
  	((u64 *)((void *)ev + sz1))[-1] = 0;
  
  	return ev;
  }
26a031e13   Andrew Vagin   perf inject: Merg...
239
240
241
  typedef int (*inject_handler)(struct perf_tool *tool,
  			      union perf_event *event,
  			      struct perf_sample *sample,
32dcd021d   Jiri Olsa   perf evsel: Renam...
242
  			      struct evsel *evsel,
26a031e13   Andrew Vagin   perf inject: Merg...
243
  			      struct machine *machine);
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
244
  static int perf_event__repipe_sample(struct perf_tool *tool,
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
245
  				     union perf_event *event,
26a031e13   Andrew Vagin   perf inject: Merg...
246
  				     struct perf_sample *sample,
32dcd021d   Jiri Olsa   perf evsel: Renam...
247
  				     struct evsel *evsel,
26a031e13   Andrew Vagin   perf inject: Merg...
248
  				     struct machine *machine)
9e69c2108   Arnaldo Carvalho de Melo   perf session: Pas...
249
  {
ba2675bf1   Adrian Hunter   perf inject: Cut ...
250
251
  	struct perf_inject *inject = container_of(tool, struct perf_inject,
  						  tool);
40978e9bf   Arnaldo Carvalho de Melo   perf inject: The ...
252
  	if (evsel && evsel->handler) {
744a97194   Arnaldo Carvalho de Melo   perf evsel: Ditch...
253
  		inject_handler f = evsel->handler;
26a031e13   Andrew Vagin   perf inject: Merg...
254
255
  		return f(tool, event, sample, evsel, machine);
  	}
54a3cf59b   Andrew Vagin   perf inject: Mark...
256
  	build_id__mark_dso_hit(tool, event, sample, evsel, machine);
ba2675bf1   Adrian Hunter   perf inject: Cut ...
257
258
  	if (inject->itrace_synth_opts.set && sample->aux_sample.size)
  		event = perf_inject__cut_auxtrace_sample(inject, event, sample);
63c2c9f8f   Adrian Hunter   perf inject: Remo...
259
  	return perf_event__repipe_synth(tool, event);
9e69c2108   Arnaldo Carvalho de Melo   perf session: Pas...
260
  }
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
261
  static int perf_event__repipe_mmap(struct perf_tool *tool,
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
262
  				   union perf_event *event,
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
263
  				   struct perf_sample *sample,
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
264
  				   struct machine *machine)
454c407ec   Tom Zanussi   perf: add perf-in...
265
266
  {
  	int err;
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
267
268
  	err = perf_event__process_mmap(tool, event, sample, machine);
  	perf_event__repipe(tool, event, sample, machine);
454c407ec   Tom Zanussi   perf: add perf-in...
269
270
271
  
  	return err;
  }
e12b202f8   Jiri Olsa   perf jitdump: Bui...
272
  #ifdef HAVE_JITDUMP
9b07e27f8   Stephane Eranian   perf inject: Add ...
273
274
275
276
277
278
279
  static int perf_event__jit_repipe_mmap(struct perf_tool *tool,
  				       union perf_event *event,
  				       struct perf_sample *sample,
  				       struct machine *machine)
  {
  	struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  	u64 n = 0;
570735b33   Adrian Hunter   perf jit: Let jit...
280
  	int ret;
9b07e27f8   Stephane Eranian   perf inject: Add ...
281
282
283
284
  
  	/*
  	 * if jit marker, then inject jit mmaps and generate ELF images
  	 */
570735b33   Adrian Hunter   perf jit: Let jit...
285
  	ret = jit_process(inject->session, &inject->output, machine,
c8f6ae1fb   Steve MacLean   perf inject jit: ...
286
  			  event->mmap.filename, event->mmap.pid, &n);
570735b33   Adrian Hunter   perf jit: Let jit...
287
288
289
  	if (ret < 0)
  		return ret;
  	if (ret) {
9b07e27f8   Stephane Eranian   perf inject: Add ...
290
291
292
293
294
295
  		inject->bytes_written += n;
  		return 0;
  	}
  	return perf_event__repipe_mmap(tool, event, sample, machine);
  }
  #endif
27c9c3424   Namhyung Kim   perf inject: Add ...
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
  static struct dso *findnew_dso(int pid, int tid, const char *filename,
  			       struct dso_id *id, struct machine *machine)
  {
  	struct thread *thread;
  	struct nsinfo *nsi = NULL;
  	struct nsinfo *nnsi;
  	struct dso *dso;
  	bool vdso;
  
  	thread = machine__findnew_thread(machine, pid, tid);
  	if (thread == NULL) {
  		pr_err("cannot find or create a task %d/%d.
  ", tid, pid);
  		return NULL;
  	}
  
  	vdso = is_vdso_map(filename);
  	nsi = nsinfo__get(thread->nsinfo);
  
  	if (vdso) {
  		/* The vdso maps are always on the host and not the
  		 * container.  Ensure that we don't use setns to look
  		 * them up.
  		 */
  		nnsi = nsinfo__copy(nsi);
  		if (nnsi) {
  			nsinfo__put(nsi);
  			nnsi->need_setns = false;
  			nsi = nnsi;
  		}
  		dso = machine__findnew_vdso(machine, thread);
  	} else {
  		dso = machine__findnew_dso_id(machine, filename, id);
  	}
  
  	if (dso)
  		dso->nsinfo = nsi;
  	else
  		nsinfo__put(nsi);
  
  	thread__put(thread);
  	return dso;
  }
  
  static int perf_event__repipe_buildid_mmap(struct perf_tool *tool,
  					   union perf_event *event,
  					   struct perf_sample *sample,
  					   struct machine *machine)
  {
  	struct dso *dso;
  
  	dso = findnew_dso(event->mmap.pid, event->mmap.tid,
  			  event->mmap.filename, NULL, machine);
  
  	if (dso && !dso->hit) {
  		dso->hit = 1;
  		dso__inject_build_id(dso, tool, machine, sample->cpumode, 0);
  		dso__put(dso);
  	}
  
  	return perf_event__repipe(tool, event, sample, machine);
  }
5c5e854bc   Stephane Eranian   perf tools: Add a...
358
359
360
361
362
363
364
365
366
367
368
369
  static int perf_event__repipe_mmap2(struct perf_tool *tool,
  				   union perf_event *event,
  				   struct perf_sample *sample,
  				   struct machine *machine)
  {
  	int err;
  
  	err = perf_event__process_mmap2(tool, event, sample, machine);
  	perf_event__repipe(tool, event, sample, machine);
  
  	return err;
  }
e12b202f8   Jiri Olsa   perf jitdump: Bui...
370
  #ifdef HAVE_JITDUMP
9b07e27f8   Stephane Eranian   perf inject: Add ...
371
372
373
374
375
376
377
  static int perf_event__jit_repipe_mmap2(struct perf_tool *tool,
  					union perf_event *event,
  					struct perf_sample *sample,
  					struct machine *machine)
  {
  	struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  	u64 n = 0;
570735b33   Adrian Hunter   perf jit: Let jit...
378
  	int ret;
9b07e27f8   Stephane Eranian   perf inject: Add ...
379
380
381
382
  
  	/*
  	 * if jit marker, then inject jit mmaps and generate ELF images
  	 */
570735b33   Adrian Hunter   perf jit: Let jit...
383
  	ret = jit_process(inject->session, &inject->output, machine,
c8f6ae1fb   Steve MacLean   perf inject jit: ...
384
  			  event->mmap2.filename, event->mmap2.pid, &n);
570735b33   Adrian Hunter   perf jit: Let jit...
385
386
387
  	if (ret < 0)
  		return ret;
  	if (ret) {
9b07e27f8   Stephane Eranian   perf inject: Add ...
388
389
390
391
392
393
  		inject->bytes_written += n;
  		return 0;
  	}
  	return perf_event__repipe_mmap2(tool, event, sample, machine);
  }
  #endif
27c9c3424   Namhyung Kim   perf inject: Add ...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
  static int perf_event__repipe_buildid_mmap2(struct perf_tool *tool,
  					    union perf_event *event,
  					    struct perf_sample *sample,
  					    struct machine *machine)
  {
  	struct dso_id dso_id = {
  		.maj = event->mmap2.maj,
  		.min = event->mmap2.min,
  		.ino = event->mmap2.ino,
  		.ino_generation = event->mmap2.ino_generation,
  	};
  	struct dso *dso;
  
  	dso = findnew_dso(event->mmap2.pid, event->mmap2.tid,
  			  event->mmap2.filename, &dso_id, machine);
  
  	if (dso && !dso->hit) {
  		dso->hit = 1;
  		dso__inject_build_id(dso, tool, machine, sample->cpumode,
  				     event->mmap2.flags);
  		dso__put(dso);
  	}
  
  	perf_event__repipe(tool, event, sample, machine);
  
  	return 0;
  }
f62d3f0f4   Arnaldo Carvalho de Melo   perf event: No ne...
421
  static int perf_event__repipe_fork(struct perf_tool *tool,
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
422
  				   union perf_event *event,
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
423
  				   struct perf_sample *sample,
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
424
  				   struct machine *machine)
454c407ec   Tom Zanussi   perf: add perf-in...
425
426
  {
  	int err;
f62d3f0f4   Arnaldo Carvalho de Melo   perf event: No ne...
427
  	err = perf_event__process_fork(tool, event, sample, machine);
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
428
  	perf_event__repipe(tool, event, sample, machine);
454c407ec   Tom Zanussi   perf: add perf-in...
429
430
431
  
  	return err;
  }
0f0aa5e06   Adrian Hunter   perf inject: Add ...
432
433
434
435
436
437
438
439
440
441
442
443
  static int perf_event__repipe_comm(struct perf_tool *tool,
  				   union perf_event *event,
  				   struct perf_sample *sample,
  				   struct machine *machine)
  {
  	int err;
  
  	err = perf_event__process_comm(tool, event, sample, machine);
  	perf_event__repipe(tool, event, sample, machine);
  
  	return err;
  }
f3b3614a2   Hari Bathini   perf tools: Add P...
444
445
446
447
448
449
450
451
452
453
454
  static int perf_event__repipe_namespaces(struct perf_tool *tool,
  					 union perf_event *event,
  					 struct perf_sample *sample,
  					 struct machine *machine)
  {
  	int err = perf_event__process_namespaces(tool, event, sample, machine);
  
  	perf_event__repipe(tool, event, sample, machine);
  
  	return err;
  }
0f0aa5e06   Adrian Hunter   perf inject: Add ...
455
456
457
458
459
460
461
462
463
464
465
466
  static int perf_event__repipe_exit(struct perf_tool *tool,
  				   union perf_event *event,
  				   struct perf_sample *sample,
  				   struct machine *machine)
  {
  	int err;
  
  	err = perf_event__process_exit(tool, event, sample, machine);
  	perf_event__repipe(tool, event, sample, machine);
  
  	return err;
  }
89f1688a5   Jiri Olsa   perf tools: Remov...
467
468
  static int perf_event__repipe_tracing_data(struct perf_session *session,
  					   union perf_event *event)
454c407ec   Tom Zanussi   perf: add perf-in...
469
470
  {
  	int err;
89f1688a5   Jiri Olsa   perf tools: Remov...
471
472
  	perf_event__repipe_synth(session->tool, event);
  	err = perf_event__process_tracing_data(session, event);
454c407ec   Tom Zanussi   perf: add perf-in...
473
474
475
  
  	return err;
  }
c824c4338   Arnaldo Carvalho de Melo   perf tools: Stop ...
476
  static int dso__read_build_id(struct dso *dso)
454c407ec   Tom Zanussi   perf: add perf-in...
477
  {
336c95b29   Namhyung Kim   perf inject: Ente...
478
  	struct nscookie nsc;
c824c4338   Arnaldo Carvalho de Melo   perf tools: Stop ...
479
  	if (dso->has_build_id)
090f7204d   Arnaldo Carvalho de Melo   perf inject: Refa...
480
  		return 0;
454c407ec   Tom Zanussi   perf: add perf-in...
481

336c95b29   Namhyung Kim   perf inject: Ente...
482
  	nsinfo__mountns_enter(dso->nsinfo, &nsc);
f766819cd   Jiri Olsa   perf tools: Pass ...
483
  	if (filename__read_build_id(dso->long_name, &dso->bid) > 0)
c824c4338   Arnaldo Carvalho de Melo   perf tools: Stop ...
484
  		dso->has_build_id = true;
336c95b29   Namhyung Kim   perf inject: Ente...
485
  	nsinfo__mountns_exit(&nsc);
454c407ec   Tom Zanussi   perf: add perf-in...
486

336c95b29   Namhyung Kim   perf inject: Ente...
487
  	return dso->has_build_id ? 0 : -1;
090f7204d   Arnaldo Carvalho de Melo   perf inject: Refa...
488
  }
454c407ec   Tom Zanussi   perf: add perf-in...
489

c824c4338   Arnaldo Carvalho de Melo   perf tools: Stop ...
490
  static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
e7b60c5a0   Namhyung Kim   perf inject: Do n...
491
  				struct machine *machine, u8 cpumode, u32 flags)
090f7204d   Arnaldo Carvalho de Melo   perf inject: Refa...
492
  {
090f7204d   Arnaldo Carvalho de Melo   perf inject: Refa...
493
  	int err;
454c407ec   Tom Zanussi   perf: add perf-in...
494

e7b60c5a0   Namhyung Kim   perf inject: Do n...
495
496
497
498
  	if (is_anon_memory(dso->long_name) || flags & MAP_HUGETLB)
  		return 0;
  	if (is_no_dso_memory(dso->long_name))
  		return 0;
c824c4338   Arnaldo Carvalho de Melo   perf tools: Stop ...
499
500
501
  	if (dso__read_build_id(dso) < 0) {
  		pr_debug("no build_id found for %s
  ", dso->long_name);
090f7204d   Arnaldo Carvalho de Melo   perf inject: Refa...
502
503
  		return -1;
  	}
454c407ec   Tom Zanussi   perf: add perf-in...
504

e7b60c5a0   Namhyung Kim   perf inject: Do n...
505
506
  	err = perf_event__synthesize_build_id(tool, dso, cpumode,
  					      perf_event__repipe, machine);
090f7204d   Arnaldo Carvalho de Melo   perf inject: Refa...
507
  	if (err) {
c824c4338   Arnaldo Carvalho de Melo   perf tools: Stop ...
508
509
  		pr_err("Can't synthesize build_id event for %s
  ", dso->long_name);
454c407ec   Tom Zanussi   perf: add perf-in...
510
511
512
513
514
  		return -1;
  	}
  
  	return 0;
  }
0bf02a0d8   Namhyung Kim   perf bench: Add b...
515
516
517
518
  int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event,
  			       struct perf_sample *sample,
  			       struct evsel *evsel __maybe_unused,
  			       struct machine *machine)
454c407ec   Tom Zanussi   perf: add perf-in...
519
520
521
  {
  	struct addr_location al;
  	struct thread *thread;
454c407ec   Tom Zanussi   perf: add perf-in...
522

13ce34df1   Namhyung Kim   perf tools: Use t...
523
  	thread = machine__findnew_thread(machine, sample->pid, sample->tid);
454c407ec   Tom Zanussi   perf: add perf-in...
524
525
526
527
  	if (thread == NULL) {
  		pr_err("problem processing %d event, skipping it.
  ",
  		       event->header.type);
454c407ec   Tom Zanussi   perf: add perf-in...
528
529
  		goto repipe;
  	}
71a84b5ae   Arnaldo Carvalho de Melo   perf thread: Make...
530
  	if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) {
454c407ec   Tom Zanussi   perf: add perf-in...
531
532
  		if (!al.map->dso->hit) {
  			al.map->dso->hit = 1;
e7b60c5a0   Namhyung Kim   perf inject: Do n...
533
534
  			dso__inject_build_id(al.map->dso, tool, machine,
  					     sample->cpumode, al.map->flags);
454c407ec   Tom Zanussi   perf: add perf-in...
535
536
  		}
  	}
b91fc39f4   Arnaldo Carvalho de Melo   perf machine: Pro...
537
  	thread__put(thread);
454c407ec   Tom Zanussi   perf: add perf-in...
538
  repipe:
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
539
  	perf_event__repipe(tool, event, sample, machine);
090f7204d   Arnaldo Carvalho de Melo   perf inject: Refa...
540
  	return 0;
454c407ec   Tom Zanussi   perf: add perf-in...
541
  }
26a031e13   Andrew Vagin   perf inject: Merg...
542
543
544
  static int perf_inject__sched_process_exit(struct perf_tool *tool,
  					   union perf_event *event __maybe_unused,
  					   struct perf_sample *sample,
32dcd021d   Jiri Olsa   perf evsel: Renam...
545
  					   struct evsel *evsel __maybe_unused,
26a031e13   Andrew Vagin   perf inject: Merg...
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
  					   struct machine *machine __maybe_unused)
  {
  	struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  	struct event_entry *ent;
  
  	list_for_each_entry(ent, &inject->samples, node) {
  		if (sample->tid == ent->tid) {
  			list_del_init(&ent->node);
  			free(ent);
  			break;
  		}
  	}
  
  	return 0;
  }
  
  static int perf_inject__sched_switch(struct perf_tool *tool,
  				     union perf_event *event,
  				     struct perf_sample *sample,
32dcd021d   Jiri Olsa   perf evsel: Renam...
565
  				     struct evsel *evsel,
26a031e13   Andrew Vagin   perf inject: Merg...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
  				     struct machine *machine)
  {
  	struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
  	struct event_entry *ent;
  
  	perf_inject__sched_process_exit(tool, event, sample, evsel, machine);
  
  	ent = malloc(event->header.size + sizeof(struct event_entry));
  	if (ent == NULL) {
  		color_fprintf(stderr, PERF_COLOR_RED,
  			     "Not enough memory to process sched switch event!");
  		return -1;
  	}
  
  	ent->tid = sample->tid;
  	memcpy(&ent->event, event, event->header.size);
  	list_add(&ent->node, &inject->samples);
  	return 0;
  }
  
  static int perf_inject__sched_stat(struct perf_tool *tool,
  				   union perf_event *event __maybe_unused,
  				   struct perf_sample *sample,
32dcd021d   Jiri Olsa   perf evsel: Renam...
589
  				   struct evsel *evsel,
26a031e13   Andrew Vagin   perf inject: Merg...
590
591
592
593
594
595
  				   struct machine *machine)
  {
  	struct event_entry *ent;
  	union perf_event *event_sw;
  	struct perf_sample sample_sw;
  	struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
efc0cdc9e   Arnaldo Carvalho de Melo   perf evsel: Renam...
596
  	u32 pid = evsel__intval(evsel, sample, "pid");
26a031e13   Andrew Vagin   perf inject: Merg...
597
598
599
600
601
602
603
604
605
  
  	list_for_each_entry(ent, &inject->samples, node) {
  		if (pid == ent->tid)
  			goto found;
  	}
  
  	return 0;
  found:
  	event_sw = &ent->event[0];
6b6017a20   Arnaldo Carvalho de Melo   perf evsel: Renam...
606
  	evsel__parse_sample(evsel, event_sw, &sample_sw);
26a031e13   Andrew Vagin   perf inject: Merg...
607
608
609
  
  	sample_sw.period = sample->period;
  	sample_sw.time	 = sample->time;
1fc632cef   Jiri Olsa   libperf: Move per...
610
611
  	perf_event__synthesize_sample(event_sw, evsel->core.attr.sample_type,
  				      evsel->core.attr.read_format, &sample_sw);
54a3cf59b   Andrew Vagin   perf inject: Mark...
612
  	build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
26a031e13   Andrew Vagin   perf inject: Merg...
613
614
  	return perf_event__repipe(tool, event_sw, &sample_sw, machine);
  }
1d037ca16   Irina Tirdea   perf tools: Use _...
615
  static void sig_handler(int sig __maybe_unused)
454c407ec   Tom Zanussi   perf: add perf-in...
616
617
618
  {
  	session_done = 1;
  }
b14b36d02   Arnaldo Carvalho de Melo   perf inject: Rena...
619
  static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg)
26a031e13   Andrew Vagin   perf inject: Merg...
620
  {
1fc632cef   Jiri Olsa   libperf: Move per...
621
  	struct perf_event_attr *attr = &evsel->core.attr;
8ab2e96d8   Arnaldo Carvalho de Melo   perf evsel: Renam...
622
  	const char *name = evsel__name(evsel);
26a031e13   Andrew Vagin   perf inject: Merg...
623
624
625
626
627
628
629
630
631
  
  	if (!(attr->sample_type & sample_type)) {
  		pr_err("Samples for %s event do not have %s attribute set.",
  			name, sample_msg);
  		return -EINVAL;
  	}
  
  	return 0;
  }
f56fb9864   Adrian Hunter   perf inject: Add ...
632
633
634
  static int drop_sample(struct perf_tool *tool __maybe_unused,
  		       union perf_event *event __maybe_unused,
  		       struct perf_sample *sample __maybe_unused,
32dcd021d   Jiri Olsa   perf evsel: Renam...
635
  		       struct evsel *evsel __maybe_unused,
f56fb9864   Adrian Hunter   perf inject: Add ...
636
637
638
639
640
641
642
  		       struct machine *machine __maybe_unused)
  {
  	return 0;
  }
  
  static void strip_init(struct perf_inject *inject)
  {
63503dba8   Jiri Olsa   perf evlist: Rena...
643
  	struct evlist *evlist = inject->session->evlist;
32dcd021d   Jiri Olsa   perf evsel: Renam...
644
  	struct evsel *evsel;
f56fb9864   Adrian Hunter   perf inject: Add ...
645
646
  
  	inject->tool.context_switch = perf_event__drop;
e5cadb93d   Arnaldo Carvalho de Melo   perf evlist: Rena...
647
  	evlist__for_each_entry(evlist, evsel)
f56fb9864   Adrian Hunter   perf inject: Add ...
648
649
  		evsel->handler = drop_sample;
  }
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
650
  static int __cmd_inject(struct perf_inject *inject)
454c407ec   Tom Zanussi   perf: add perf-in...
651
  {
454c407ec   Tom Zanussi   perf: add perf-in...
652
  	int ret = -EINVAL;
1cb8bdcca   Namhyung Kim   perf inject: Move...
653
  	struct perf_session *session = inject->session;
8ceb41d7e   Jiri Olsa   perf tools: Renam...
654
655
  	struct perf_data *data_out = &inject->output;
  	int fd = perf_data__fd(data_out);
0f0aa5e06   Adrian Hunter   perf inject: Add ...
656
  	u64 output_data_offset;
454c407ec   Tom Zanussi   perf: add perf-in...
657
658
  
  	signal(SIGINT, sig_handler);
0f0aa5e06   Adrian Hunter   perf inject: Add ...
659
  	if (inject->build_ids || inject->sched_stat ||
27c9c3424   Namhyung Kim   perf inject: Add ...
660
  	    inject->itrace_synth_opts.set || inject->build_id_all) {
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
661
  		inject->tool.mmap	  = perf_event__repipe_mmap;
5c5e854bc   Stephane Eranian   perf tools: Add a...
662
  		inject->tool.mmap2	  = perf_event__repipe_mmap2;
f62d3f0f4   Arnaldo Carvalho de Melo   perf event: No ne...
663
  		inject->tool.fork	  = perf_event__repipe_fork;
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
664
  		inject->tool.tracing_data = perf_event__repipe_tracing_data;
454c407ec   Tom Zanussi   perf: add perf-in...
665
  	}
0f0aa5e06   Adrian Hunter   perf inject: Add ...
666
  	output_data_offset = session->header.data_offset;
27c9c3424   Namhyung Kim   perf inject: Add ...
667
668
669
670
  	if (inject->build_id_all) {
  		inject->tool.mmap	  = perf_event__repipe_buildid_mmap;
  		inject->tool.mmap2	  = perf_event__repipe_buildid_mmap2;
  	} else if (inject->build_ids) {
54a3cf59b   Andrew Vagin   perf inject: Mark...
671
672
  		inject->tool.sample = perf_event__inject_buildid;
  	} else if (inject->sched_stat) {
32dcd021d   Jiri Olsa   perf evsel: Renam...
673
  		struct evsel *evsel;
26a031e13   Andrew Vagin   perf inject: Merg...
674

e5cadb93d   Arnaldo Carvalho de Melo   perf evlist: Rena...
675
  		evlist__for_each_entry(session->evlist, evsel) {
8ab2e96d8   Arnaldo Carvalho de Melo   perf evsel: Renam...
676
  			const char *name = evsel__name(evsel);
26a031e13   Andrew Vagin   perf inject: Merg...
677
678
  
  			if (!strcmp(name, "sched:sched_switch")) {
b14b36d02   Arnaldo Carvalho de Melo   perf inject: Rena...
679
  				if (evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID"))
26a031e13   Andrew Vagin   perf inject: Merg...
680
  					return -EINVAL;
744a97194   Arnaldo Carvalho de Melo   perf evsel: Ditch...
681
  				evsel->handler = perf_inject__sched_switch;
26a031e13   Andrew Vagin   perf inject: Merg...
682
  			} else if (!strcmp(name, "sched:sched_process_exit"))
744a97194   Arnaldo Carvalho de Melo   perf evsel: Ditch...
683
  				evsel->handler = perf_inject__sched_process_exit;
26a031e13   Andrew Vagin   perf inject: Merg...
684
  			else if (!strncmp(name, "sched:sched_stat_", 17))
744a97194   Arnaldo Carvalho de Melo   perf evsel: Ditch...
685
  				evsel->handler = perf_inject__sched_stat;
26a031e13   Andrew Vagin   perf inject: Merg...
686
  		}
0f0aa5e06   Adrian Hunter   perf inject: Add ...
687
688
689
690
  	} else if (inject->itrace_synth_opts.set) {
  		session->itrace_synth_opts = &inject->itrace_synth_opts;
  		inject->itrace_synth_opts.inject = true;
  		inject->tool.comm	    = perf_event__repipe_comm;
f3b3614a2   Hari Bathini   perf tools: Add P...
691
  		inject->tool.namespaces	    = perf_event__repipe_namespaces;
0f0aa5e06   Adrian Hunter   perf inject: Add ...
692
  		inject->tool.exit	    = perf_event__repipe_exit;
29f6eeca0   Adrian Hunter   perf inject: Fix ...
693
  		inject->tool.id_index	    = perf_event__process_id_index;
0f0aa5e06   Adrian Hunter   perf inject: Add ...
694
695
  		inject->tool.auxtrace_info  = perf_event__process_auxtrace_info;
  		inject->tool.auxtrace	    = perf_event__process_auxtrace;
73117308f   Adrian Hunter   perf inject: Remo...
696
697
  		inject->tool.aux	    = perf_event__drop_aux;
  		inject->tool.itrace_start   = perf_event__drop_aux,
0f0aa5e06   Adrian Hunter   perf inject: Add ...
698
699
700
701
  		inject->tool.ordered_events = true;
  		inject->tool.ordering_requires_timestamps = true;
  		/* Allow space in the header for new attributes */
  		output_data_offset = 4096;
f56fb9864   Adrian Hunter   perf inject: Add ...
702
703
  		if (inject->strip)
  			strip_init(inject);
26a031e13   Andrew Vagin   perf inject: Merg...
704
  	}
99fa29845   Adrian Hunter   perf tools: Add A...
705
706
  	if (!inject->itrace_synth_opts.set)
  		auxtrace_index__free(&session->auxtrace_index);
8ceb41d7e   Jiri Olsa   perf tools: Renam...
707
  	if (!data_out->is_pipe)
0f0aa5e06   Adrian Hunter   perf inject: Add ...
708
  		lseek(fd, output_data_offset, SEEK_SET);
e558a5bd8   Andrew Vagin   perf inject: Work...
709

b7b61cbeb   Arnaldo Carvalho de Melo   perf ordered_even...
710
  	ret = perf_session__process_events(session);
bb8d521f7   David Carrillo-Cisneros   perf inject: Don'...
711
712
  	if (ret)
  		return ret;
454c407ec   Tom Zanussi   perf: add perf-in...
713

8ceb41d7e   Jiri Olsa   perf tools: Renam...
714
  	if (!data_out->is_pipe) {
640dad479   Adrian Hunter   perf inject: Hit ...
715
  		if (inject->build_ids)
e38b43c3f   Adrian Hunter   perf inject: Fix ...
716
717
  			perf_header__set_feat(&session->header,
  					      HEADER_BUILD_ID);
640dad479   Adrian Hunter   perf inject: Hit ...
718
719
720
721
722
723
724
  		/*
  		 * Keep all buildids when there is unprocessed AUX data because
  		 * it is not known which ones the AUX trace hits.
  		 */
  		if (perf_header__has_feat(&session->header, HEADER_BUILD_ID) &&
  		    inject->have_auxtrace && !inject->itrace_synth_opts.set)
  			dsos__hit_all(session);
0f0aa5e06   Adrian Hunter   perf inject: Add ...
725
726
  		/*
  		 * The AUX areas have been removed and replaced with
1c756cd42   Al Grant   perf inject: Fix ...
727
  		 * synthesized hardware events, so clear the feature flag.
0f0aa5e06   Adrian Hunter   perf inject: Add ...
728
  		 */
051a01b9a   Adrian Hunter   perf inject: Set ...
729
  		if (inject->itrace_synth_opts.set) {
0f0aa5e06   Adrian Hunter   perf inject: Add ...
730
731
  			perf_header__clear_feat(&session->header,
  						HEADER_AUXTRACE);
ec90e42ce   Adrian Hunter   perf auxtrace: Ad...
732
733
  			if (inject->itrace_synth_opts.last_branch ||
  			    inject->itrace_synth_opts.add_last_branch)
051a01b9a   Adrian Hunter   perf inject: Set ...
734
735
736
  				perf_header__set_feat(&session->header,
  						      HEADER_BRANCH_STACK);
  		}
0f0aa5e06   Adrian Hunter   perf inject: Add ...
737
  		session->header.data_offset = output_data_offset;
e558a5bd8   Andrew Vagin   perf inject: Work...
738
  		session->header.data_size = inject->bytes_written;
42aa276f4   Namhyung Kim   perf tools: Use p...
739
  		perf_session__write_header(session, session->evlist, fd, true);
e558a5bd8   Andrew Vagin   perf inject: Work...
740
  	}
454c407ec   Tom Zanussi   perf: add perf-in...
741
742
  	return ret;
  }
b0ad8ea66   Arnaldo Carvalho de Melo   perf tools: Remov...
743
  int cmd_inject(int argc, const char **argv)
454c407ec   Tom Zanussi   perf: add perf-in...
744
  {
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
745
746
747
  	struct perf_inject inject = {
  		.tool = {
  			.sample		= perf_event__repipe_sample,
2946ecedd   Namhyung Kim   perf inject: Add ...
748
  			.read		= perf_event__repipe_sample,
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
749
  			.mmap		= perf_event__repipe,
5c5e854bc   Stephane Eranian   perf tools: Add a...
750
  			.mmap2		= perf_event__repipe,
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
751
  			.comm		= perf_event__repipe,
2946ecedd   Namhyung Kim   perf inject: Add ...
752
753
  			.namespaces	= perf_event__repipe,
  			.cgroup		= perf_event__repipe,
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
754
755
756
  			.fork		= perf_event__repipe,
  			.exit		= perf_event__repipe,
  			.lost		= perf_event__repipe,
d8145b3e3   Adrian Hunter   perf inject: Also...
757
  			.lost_samples	= perf_event__repipe,
4a96f7a02   Adrian Hunter   perf tools: Add s...
758
  			.aux		= perf_event__repipe,
0ad21f686   Adrian Hunter   perf tools: Add s...
759
  			.itrace_start	= perf_event__repipe,
0286039f7   Adrian Hunter   perf tools: Add n...
760
  			.context_switch	= perf_event__repipe,
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
761
762
  			.throttle	= perf_event__repipe,
  			.unthrottle	= perf_event__repipe,
2946ecedd   Namhyung Kim   perf inject: Add ...
763
764
765
  			.ksymbol	= perf_event__repipe,
  			.bpf		= perf_event__repipe,
  			.text_poke	= perf_event__repipe,
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
766
  			.attr		= perf_event__repipe_attr,
2946ecedd   Namhyung Kim   perf inject: Add ...
767
  			.event_update	= perf_event__repipe_event_update,
47c3d1091   Adrian Hunter   perf tools: Fix m...
768
  			.tracing_data	= perf_event__repipe_op2_synth,
d704ebdae   Arnaldo Carvalho de Melo   perf tools: tool-...
769
  			.finished_round	= perf_event__repipe_oe_synth,
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
770
  			.build_id	= perf_event__repipe_op2_synth,
3c659eeda   Adrian Hunter   perf tools: Add i...
771
  			.id_index	= perf_event__repipe_op2_synth,
2946ecedd   Namhyung Kim   perf inject: Add ...
772
773
774
775
776
777
778
779
  			.auxtrace_info	= perf_event__repipe_op2_synth,
  			.auxtrace_error	= perf_event__repipe_op2_synth,
  			.time_conv	= perf_event__repipe_op2_synth,
  			.thread_map	= perf_event__repipe_op2_synth,
  			.cpu_map	= perf_event__repipe_op2_synth,
  			.stat_config	= perf_event__repipe_op2_synth,
  			.stat		= perf_event__repipe_op2_synth,
  			.stat_round	= perf_event__repipe_op2_synth,
e9def1b2e   David Carrillo-Cisneros   perf tools: Add f...
780
  			.feature	= perf_event__repipe_op2_synth,
2946ecedd   Namhyung Kim   perf inject: Add ...
781
782
  			.compressed	= perf_event__repipe_op4_synth,
  			.auxtrace	= perf_event__repipe_auxtrace,
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
783
  		},
e558a5bd8   Andrew Vagin   perf inject: Work...
784
  		.input_name  = "-",
26a031e13   Andrew Vagin   perf inject: Merg...
785
  		.samples = LIST_HEAD_INIT(inject.samples),
3406912cc   Jiri Olsa   perf inject: Hand...
786
  		.output = {
2d4f27999   Jiri Olsa   perf data: Add gl...
787
788
  			.path = "-",
  			.mode = PERF_DATA_MODE_WRITE,
3406912cc   Jiri Olsa   perf inject: Hand...
789
  		},
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
790
  	};
8ceb41d7e   Jiri Olsa   perf tools: Renam...
791
  	struct perf_data data = {
1cb8bdcca   Namhyung Kim   perf inject: Move...
792
793
794
  		.mode = PERF_DATA_MODE_READ,
  	};
  	int ret;
9b07e27f8   Stephane Eranian   perf inject: Add ...
795
  	struct option options[] = {
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
796
797
  		OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
  			    "Inject build-ids into the output stream"),
27c9c3424   Namhyung Kim   perf inject: Add ...
798
799
  		OPT_BOOLEAN(0, "buildid-all", &inject.build_id_all,
  			    "Inject build-ids of all DSOs into the output stream"),
e558a5bd8   Andrew Vagin   perf inject: Work...
800
801
  		OPT_STRING('i', "input", &inject.input_name, "file",
  			   "input file name"),
2d4f27999   Jiri Olsa   perf data: Add gl...
802
  		OPT_STRING('o', "output", &inject.output.path, "file",
e558a5bd8   Andrew Vagin   perf inject: Work...
803
  			   "output file name"),
26a031e13   Andrew Vagin   perf inject: Merg...
804
805
806
  		OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat,
  			    "Merge sched-stat and sched-switch for getting events "
  			    "where and how long tasks slept"),
e12b202f8   Jiri Olsa   perf jitdump: Bui...
807
  #ifdef HAVE_JITDUMP
9b07e27f8   Stephane Eranian   perf inject: Add ...
808
  		OPT_BOOLEAN('j', "jit", &inject.jit_mode, "merge jitdump files into perf.data file"),
e12b202f8   Jiri Olsa   perf jitdump: Bui...
809
  #endif
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
810
811
  		OPT_INCR('v', "verbose", &verbose,
  			 "be more verbose (show build ids, etc)"),
a7a2b8b4c   Adrian Hunter   perf inject: Add ...
812
813
  		OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file",
  			   "kallsyms pathname"),
8ceb41d7e   Jiri Olsa   perf tools: Renam...
814
  		OPT_BOOLEAN('f', "force", &data.force, "don't complain, do it"),
0f0aa5e06   Adrian Hunter   perf inject: Add ...
815
  		OPT_CALLBACK_OPTARG(0, "itrace", &inject.itrace_synth_opts,
c12e039d1   Andi Kleen   perf tools: Repor...
816
817
818
  				    NULL, "opts", "Instruction Tracing options
  "
  				    ITRACE_HELP,
0f0aa5e06   Adrian Hunter   perf inject: Add ...
819
  				    itrace_parse_synth_opts),
f56fb9864   Adrian Hunter   perf inject: Add ...
820
821
  		OPT_BOOLEAN(0, "strip", &inject.strip,
  			    "strip non-synthesized events (use with --itrace)"),
5ded57ac1   Arnaldo Carvalho de Melo   perf inject: Remo...
822
823
  		OPT_END()
  	};
002439e84   Arnaldo Carvalho de Melo   perf inject: Don'...
824
825
826
827
  	const char * const inject_usage[] = {
  		"perf inject [<options>]",
  		NULL
  	};
e12b202f8   Jiri Olsa   perf jitdump: Bui...
828
  #ifndef HAVE_JITDUMP
9b07e27f8   Stephane Eranian   perf inject: Add ...
829
830
  	set_option_nobuild(options, 'j', "jit", "NO_LIBELF=1", true);
  #endif
002439e84   Arnaldo Carvalho de Melo   perf inject: Don'...
831
  	argc = parse_options(argc, argv, options, inject_usage, 0);
454c407ec   Tom Zanussi   perf: add perf-in...
832
833
834
835
836
  
  	/*
  	 * Any (unrecognized) arguments left?
  	 */
  	if (argc)
002439e84   Arnaldo Carvalho de Melo   perf inject: Don'...
837
  		usage_with_options(inject_usage, options);
454c407ec   Tom Zanussi   perf: add perf-in...
838

f56fb9864   Adrian Hunter   perf inject: Add ...
839
840
841
842
843
  	if (inject.strip && !inject.itrace_synth_opts.set) {
  		pr_err("--strip option requires --itrace option
  ");
  		return -1;
  	}
8ceb41d7e   Jiri Olsa   perf tools: Renam...
844
  	if (perf_data__open(&inject.output)) {
3406912cc   Jiri Olsa   perf inject: Hand...
845
846
  		perror("failed to create output file");
  		return -1;
e558a5bd8   Andrew Vagin   perf inject: Work...
847
  	}
2d4f27999   Jiri Olsa   perf data: Add gl...
848
  	data.path = inject.input_name;
8ceb41d7e   Jiri Olsa   perf tools: Renam...
849
  	inject.session = perf_session__new(&data, true, &inject.tool);
6ef81c55a   Mamatha Inamdar   perf session: Ret...
850
851
  	if (IS_ERR(inject.session))
  		return PTR_ERR(inject.session);
1cb8bdcca   Namhyung Kim   perf inject: Move...
852

371a3378d   Alexey Budankov   perf inject: Enab...
853
854
855
  	if (zstd_init(&(inject.session->zstd_data), 0) < 0)
  		pr_warning("Decompression initialization failed.
  ");
27c9c3424   Namhyung Kim   perf inject: Add ...
856
  	if (inject.build_ids && !inject.build_id_all) {
921f3fadb   Arnaldo Carvalho de Melo   perf inject: Make...
857
858
859
860
861
862
863
864
865
  		/*
  		 * to make sure the mmap records are ordered correctly
  		 * and so that the correct especially due to jitted code
  		 * mmaps. We cannot generate the buildid hit list and
  		 * inject the jit mmaps at the same time for now.
  		 */
  		inject.tool.ordered_events = true;
  		inject.tool.ordering_requires_timestamps = true;
  	}
27c9c3424   Namhyung Kim   perf inject: Add ...
866
867
868
869
  
  	if (inject.sched_stat) {
  		inject.tool.ordered_events = true;
  	}
e12b202f8   Jiri Olsa   perf jitdump: Bui...
870
  #ifdef HAVE_JITDUMP
9b07e27f8   Stephane Eranian   perf inject: Add ...
871
  	if (inject.jit_mode) {
9b07e27f8   Stephane Eranian   perf inject: Add ...
872
873
874
875
876
877
878
879
880
881
882
  		inject.tool.mmap2	   = perf_event__jit_repipe_mmap2;
  		inject.tool.mmap	   = perf_event__jit_repipe_mmap;
  		inject.tool.ordered_events = true;
  		inject.tool.ordering_requires_timestamps = true;
  		/*
  		 * JIT MMAP injection injects all MMAP events in one go, so it
  		 * does not obey finished_round semantics.
  		 */
  		inject.tool.finished_round = perf_event__drop_oe;
  	}
  #endif
9fedfb0c5   Taeung Song   perf inject: Fill...
883
884
885
  	ret = symbol__init(&inject.session->header.env);
  	if (ret < 0)
  		goto out_delete;
454c407ec   Tom Zanussi   perf: add perf-in...
886

1cb8bdcca   Namhyung Kim   perf inject: Move...
887
  	ret = __cmd_inject(&inject);
9fedfb0c5   Taeung Song   perf inject: Fill...
888
  out_delete:
371a3378d   Alexey Budankov   perf inject: Enab...
889
  	zstd_fini(&(inject.session->zstd_data));
1cb8bdcca   Namhyung Kim   perf inject: Move...
890
  	perf_session__delete(inject.session);
1cb8bdcca   Namhyung Kim   perf inject: Move...
891
  	return ret;
454c407ec   Tom Zanussi   perf: add perf-in...
892
  }