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