1e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/*
2e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * builtin-inject.c
3e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *
4e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Builtin inject command: Examine the live mode (stdin) event stream
5e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * and repipe it to stdout while optionally injecting additional
6e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * events into it.
7e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */
8e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "builtin.h"
9e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
10e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "perf.h"
11e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/session.h"
12e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/debug.h"
13e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
14e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util/parse-options.h"
15e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
16e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic char		const *input_name = "-";
17e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic bool		inject_build_ids;
18e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
19e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int perf_event__repipe_synth(union perf_event *event,
20e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				    struct perf_session *session __used)
21e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
22e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	uint32_t size;
23e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	void *buf = event;
24e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
25e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	size = event->header.size;
26e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
27e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	while (size) {
28e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		int ret = write(STDOUT_FILENO, buf, size);
29e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		if (ret < 0)
30e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			return -errno;
31e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
32e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		size -= ret;
33e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		buf += ret;
34e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
35e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
36e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return 0;
37e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
38e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
39e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int perf_event__repipe(union perf_event *event,
40e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			      struct perf_sample *sample __used,
41e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			      struct perf_session *session)
42e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
43e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return perf_event__repipe_synth(event, session);
44e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
45e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
46e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int perf_event__repipe_sample(union perf_event *event,
47e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			      struct perf_sample *sample __used,
48e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			      struct perf_evsel *evsel __used,
49e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			      struct perf_session *session)
50e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
51e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return perf_event__repipe_synth(event, session);
52e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
53e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
54e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int perf_event__repipe_mmap(union perf_event *event,
55e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				   struct perf_sample *sample,
56e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				   struct perf_session *session)
57e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
58e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	int err;
59e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
60e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	err = perf_event__process_mmap(event, sample, session);
61e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	perf_event__repipe(event, sample, session);
62e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
63e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return err;
64e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
65e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
66e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int perf_event__repipe_task(union perf_event *event,
67e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				   struct perf_sample *sample,
68e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				   struct perf_session *session)
69e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
70e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	int err;
71e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
72e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	err = perf_event__process_task(event, sample, session);
73e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	perf_event__repipe(event, sample, session);
74e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
75e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return err;
76e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
77e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
78e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int perf_event__repipe_tracing_data(union perf_event *event,
79e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng					   struct perf_session *session)
80e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
81e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	int err;
82e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
83e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	perf_event__repipe_synth(event, session);
84e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	err = perf_event__process_tracing_data(event, session);
85e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
86e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return err;
87e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
88e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
89e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int dso__read_build_id(struct dso *self)
90e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
91e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (self->has_build_id)
92e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		return 0;
93e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
94e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (filename__read_build_id(self->long_name, self->build_id,
95e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				    sizeof(self->build_id)) > 0) {
96e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		self->has_build_id = true;
97e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		return 0;
98e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
99e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
100e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return -1;
101e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
102e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
103e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int dso__inject_build_id(struct dso *self, struct perf_session *session)
104e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
105e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	u16 misc = PERF_RECORD_MISC_USER;
106e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	struct machine *machine;
107e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	int err;
108e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
109e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (dso__read_build_id(self) < 0) {
110e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		pr_debug("no build_id found for %s\n", self->long_name);
111e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		return -1;
112e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
113e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
114e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	machine = perf_session__find_host_machine(session);
115e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (machine == NULL) {
116e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		pr_err("Can't find machine for session\n");
117e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		return -1;
118e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
119e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
120e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (self->kernel)
121e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		misc = PERF_RECORD_MISC_KERNEL;
122e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
123e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	err = perf_event__synthesize_build_id(self, misc, perf_event__repipe,
124e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng					      machine, session);
125e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (err) {
126e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		pr_err("Can't synthesize build_id event for %s\n", self->long_name);
127e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		return -1;
128e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
129e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
130e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return 0;
131e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
132e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
133e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int perf_event__inject_buildid(union perf_event *event,
134e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				      struct perf_sample *sample,
135e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				      struct perf_evsel *evsel __used,
136e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				      struct perf_session *session)
137e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
138e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	struct addr_location al;
139e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	struct thread *thread;
140e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	u8 cpumode;
141e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
142e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
143e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
144e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	thread = perf_session__findnew(session, event->ip.pid);
145e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (thread == NULL) {
146e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		pr_err("problem processing %d event, skipping it.\n",
147e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		       event->header.type);
148e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		goto repipe;
149e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
150e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
151e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
152e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			      event->ip.pid, event->ip.ip, &al);
153e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
154e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (al.map != NULL) {
155e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		if (!al.map->dso->hit) {
156e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			al.map->dso->hit = 1;
157e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			if (map__load(al.map, NULL) >= 0) {
158e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				dso__inject_build_id(al.map->dso, session);
159e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				/*
160e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				 * If this fails, too bad, let the other side
161e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				 * account this as unresolved.
162e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				 */
163e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			} else
164e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng				pr_warning("no symbols found in %s, maybe "
165e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng					   "install a debug package?\n",
166e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng					   al.map->dso->long_name);
167e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		}
168e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
169e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
170e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengrepipe:
171e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	perf_event__repipe(event, sample, session);
172e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return 0;
173e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
174e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
175e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct perf_event_ops inject_ops = {
176e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.sample		= perf_event__repipe_sample,
177e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.mmap		= perf_event__repipe,
178e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.comm		= perf_event__repipe,
179e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.fork		= perf_event__repipe,
180e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.exit		= perf_event__repipe,
181e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.lost		= perf_event__repipe,
182e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.read		= perf_event__repipe,
183e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.throttle	= perf_event__repipe,
184e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.unthrottle	= perf_event__repipe,
185e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.attr		= perf_event__repipe_synth,
186e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.event_type 	= perf_event__repipe_synth,
187e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.tracing_data 	= perf_event__repipe_synth,
188e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	.build_id 	= perf_event__repipe_synth,
189e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng};
190e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
191e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengextern volatile int session_done;
192e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
193e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void sig_handler(int sig __attribute__((__unused__)))
194e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
195e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	session_done = 1;
196e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
197e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
198e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int __cmd_inject(void)
199e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
200e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	struct perf_session *session;
201e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	int ret = -EINVAL;
202e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
203e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	signal(SIGINT, sig_handler);
204e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
205e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (inject_build_ids) {
206e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		inject_ops.sample	= perf_event__inject_buildid;
207e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		inject_ops.mmap		= perf_event__repipe_mmap;
208e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		inject_ops.fork		= perf_event__repipe_task;
209e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		inject_ops.tracing_data	= perf_event__repipe_tracing_data;
210e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
211e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
212e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	session = perf_session__new(input_name, O_RDONLY, false, true, &inject_ops);
213e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (session == NULL)
214e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		return -ENOMEM;
215e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
216e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	ret = perf_session__process_events(session, &inject_ops);
217e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
218e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	perf_session__delete(session);
219e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
220e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return ret;
221e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
222e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
223e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const char * const report_usage[] = {
224e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	"perf inject [<options>]",
225e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	NULL
226e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng};
227e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
228e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const struct option options[] = {
229e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	OPT_BOOLEAN('b', "build-ids", &inject_build_ids,
230e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		    "Inject build-ids into the output stream"),
231e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	OPT_INCR('v', "verbose", &verbose,
232e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		 "be more verbose (show build ids, etc)"),
233e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	OPT_END()
234e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng};
235e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
236e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint cmd_inject(int argc, const char **argv, const char *prefix __used)
237e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
238e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	argc = parse_options(argc, argv, options, report_usage, 0);
239e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
240e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	/*
241e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	 * Any (unrecognized) arguments left?
242e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	 */
243e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (argc)
244e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		usage_with_options(report_usage, options);
245e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
246e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (symbol__init() < 0)
247e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		return -1;
248e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
249e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return __cmd_inject();
250e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
251