182d156cdSTom Zanussi /*
2133dc4c3SIngo Molnar * trace-event-perl. Feed perf script events to an embedded Perl interpreter.
382d156cdSTom Zanussi *
482d156cdSTom Zanussi * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
582d156cdSTom Zanussi *
682d156cdSTom Zanussi * This program is free software; you can redistribute it and/or modify
782d156cdSTom Zanussi * it under the terms of the GNU General Public License as published by
882d156cdSTom Zanussi * the Free Software Foundation; either version 2 of the License, or
982d156cdSTom Zanussi * (at your option) any later version.
1082d156cdSTom Zanussi *
1182d156cdSTom Zanussi * This program is distributed in the hope that it will be useful,
1282d156cdSTom Zanussi * but WITHOUT ANY WARRANTY; without even the implied warranty of
1382d156cdSTom Zanussi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1482d156cdSTom Zanussi * GNU General Public License for more details.
1582d156cdSTom Zanussi *
1682d156cdSTom Zanussi * You should have received a copy of the GNU General Public License
1782d156cdSTom Zanussi * along with this program; if not, write to the Free Software
1882d156cdSTom Zanussi * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1982d156cdSTom Zanussi *
2082d156cdSTom Zanussi */
2182d156cdSTom Zanussi
22fd20e811SArnaldo Carvalho de Melo #include <inttypes.h>
2382d156cdSTom Zanussi #include <stdio.h>
2482d156cdSTom Zanussi #include <stdlib.h>
2582d156cdSTom Zanussi #include <string.h>
2682d156cdSTom Zanussi #include <ctype.h>
2782d156cdSTom Zanussi #include <errno.h>
28cdae2d1eSJiri Olsa #include <linux/bitmap.h>
29bd48c63eSArnaldo Carvalho de Melo #include <linux/time64.h>
30378ef0f5SIan Rogers #include <traceevent/event-parse.h>
3182d156cdSTom Zanussi
327de96c3eSArnaldo Carvalho de Melo #include <stdbool.h>
337de96c3eSArnaldo Carvalho de Melo /* perl needs the following define, right after including stdbool.h */
347de96c3eSArnaldo Carvalho de Melo #define HAS_BOOL
3512046099SDavid Ahern #include <EXTERN.h>
3612046099SDavid Ahern #include <perl.h>
3712046099SDavid Ahern
38f7380c12SDima Kogan #include "../callchain.h"
394a3cec84SArnaldo Carvalho de Melo #include "../dso.h"
40f7380c12SDima Kogan #include "../machine.h"
411101f69aSArnaldo Carvalho de Melo #include "../map.h"
42daecf9e0SArnaldo Carvalho de Melo #include "../symbol.h"
43743eb868SArnaldo Carvalho de Melo #include "../thread.h"
44743eb868SArnaldo Carvalho de Melo #include "../event.h"
4582d156cdSTom Zanussi #include "../trace-event.h"
4637a058eaSRobert Richter #include "../evsel.h"
4784f5d36fSJiri Olsa #include "../debug.h"
4882d156cdSTom Zanussi
4982d156cdSTom Zanussi void boot_Perf__Trace__Context(pTHX_ CV *cv);
5082d156cdSTom Zanussi void boot_DynaLoader(pTHX_ CV *cv);
5182d156cdSTom Zanussi typedef PerlInterpreter * INTERP;
5282d156cdSTom Zanussi
5382d156cdSTom Zanussi void xs_init(pTHX);
5482d156cdSTom Zanussi
xs_init(pTHX)5582d156cdSTom Zanussi void xs_init(pTHX)
5682d156cdSTom Zanussi {
5782d156cdSTom Zanussi const char *file = __FILE__;
5882d156cdSTom Zanussi dXSUB_SYS;
5982d156cdSTom Zanussi
6082d156cdSTom Zanussi newXS("Perf::Trace::Context::bootstrap", boot_Perf__Trace__Context,
6182d156cdSTom Zanussi file);
6282d156cdSTom Zanussi newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
6382d156cdSTom Zanussi }
6482d156cdSTom Zanussi
6582d156cdSTom Zanussi INTERP my_perl;
6682d156cdSTom Zanussi
67609a7404SSteven Rostedt (Red Hat) #define TRACE_EVENT_TYPE_MAX \
6882d156cdSTom Zanussi ((1 << (sizeof(unsigned short) * 8)) - 1)
6982d156cdSTom Zanussi
70609a7404SSteven Rostedt (Red Hat) extern struct scripting_context *scripting_context;
7182d156cdSTom Zanussi
7282d156cdSTom Zanussi static char *cur_field_name;
7382d156cdSTom Zanussi static int zero_flag_atom;
7482d156cdSTom Zanussi
define_symbolic_value(const char * ev_name,const char * field_name,const char * field_value,const char * field_str)7582d156cdSTom Zanussi static void define_symbolic_value(const char *ev_name,
7682d156cdSTom Zanussi const char *field_name,
7782d156cdSTom Zanussi const char *field_value,
7882d156cdSTom Zanussi const char *field_str)
7982d156cdSTom Zanussi {
8082d156cdSTom Zanussi unsigned long long value;
8182d156cdSTom Zanussi dSP;
8282d156cdSTom Zanussi
8382d156cdSTom Zanussi value = eval_flag(field_value);
8482d156cdSTom Zanussi
8582d156cdSTom Zanussi ENTER;
8682d156cdSTom Zanussi SAVETMPS;
8782d156cdSTom Zanussi PUSHMARK(SP);
8882d156cdSTom Zanussi
8982d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
9082d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
9182d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVuv(value)));
9282d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(field_str, 0)));
9382d156cdSTom Zanussi
9482d156cdSTom Zanussi PUTBACK;
9582d156cdSTom Zanussi if (get_cv("main::define_symbolic_value", 0))
9682d156cdSTom Zanussi call_pv("main::define_symbolic_value", G_SCALAR);
9782d156cdSTom Zanussi SPAGAIN;
9882d156cdSTom Zanussi PUTBACK;
9982d156cdSTom Zanussi FREETMPS;
10082d156cdSTom Zanussi LEAVE;
10182d156cdSTom Zanussi }
10282d156cdSTom Zanussi
define_symbolic_values(struct tep_print_flag_sym * field,const char * ev_name,const char * field_name)10382d156cdSTom Zanussi static void define_symbolic_values(struct tep_print_flag_sym *field,
10482d156cdSTom Zanussi const char *ev_name,
1055647f94bSTzvetomir Stoyanov (VMware) const char *field_name)
10682d156cdSTom Zanussi {
10782d156cdSTom Zanussi define_symbolic_value(ev_name, field_name, field->value, field->str);
10882d156cdSTom Zanussi if (field->next)
10982d156cdSTom Zanussi define_symbolic_values(field->next, ev_name, field_name);
11082d156cdSTom Zanussi }
11182d156cdSTom Zanussi
define_symbolic_field(const char * ev_name,const char * field_name)11282d156cdSTom Zanussi static void define_symbolic_field(const char *ev_name,
11382d156cdSTom Zanussi const char *field_name)
11482d156cdSTom Zanussi {
11582d156cdSTom Zanussi dSP;
11682d156cdSTom Zanussi
11782d156cdSTom Zanussi ENTER;
11882d156cdSTom Zanussi SAVETMPS;
11982d156cdSTom Zanussi PUSHMARK(SP);
12082d156cdSTom Zanussi
12182d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
12282d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
12382d156cdSTom Zanussi
12482d156cdSTom Zanussi PUTBACK;
12582d156cdSTom Zanussi if (get_cv("main::define_symbolic_field", 0))
12682d156cdSTom Zanussi call_pv("main::define_symbolic_field", G_SCALAR);
12782d156cdSTom Zanussi SPAGAIN;
12882d156cdSTom Zanussi PUTBACK;
12982d156cdSTom Zanussi FREETMPS;
13082d156cdSTom Zanussi LEAVE;
13182d156cdSTom Zanussi }
13282d156cdSTom Zanussi
define_flag_value(const char * ev_name,const char * field_name,const char * field_value,const char * field_str)13382d156cdSTom Zanussi static void define_flag_value(const char *ev_name,
13482d156cdSTom Zanussi const char *field_name,
13582d156cdSTom Zanussi const char *field_value,
13682d156cdSTom Zanussi const char *field_str)
13782d156cdSTom Zanussi {
13882d156cdSTom Zanussi unsigned long long value;
13982d156cdSTom Zanussi dSP;
14082d156cdSTom Zanussi
14182d156cdSTom Zanussi value = eval_flag(field_value);
14282d156cdSTom Zanussi
14382d156cdSTom Zanussi ENTER;
14482d156cdSTom Zanussi SAVETMPS;
14582d156cdSTom Zanussi PUSHMARK(SP);
14682d156cdSTom Zanussi
14782d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
14882d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
14982d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVuv(value)));
15082d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(field_str, 0)));
15182d156cdSTom Zanussi
15282d156cdSTom Zanussi PUTBACK;
15382d156cdSTom Zanussi if (get_cv("main::define_flag_value", 0))
15482d156cdSTom Zanussi call_pv("main::define_flag_value", G_SCALAR);
15582d156cdSTom Zanussi SPAGAIN;
15682d156cdSTom Zanussi PUTBACK;
15782d156cdSTom Zanussi FREETMPS;
15882d156cdSTom Zanussi LEAVE;
15982d156cdSTom Zanussi }
16082d156cdSTom Zanussi
define_flag_values(struct tep_print_flag_sym * field,const char * ev_name,const char * field_name)16182d156cdSTom Zanussi static void define_flag_values(struct tep_print_flag_sym *field,
16282d156cdSTom Zanussi const char *ev_name,
1635647f94bSTzvetomir Stoyanov (VMware) const char *field_name)
16482d156cdSTom Zanussi {
16582d156cdSTom Zanussi define_flag_value(ev_name, field_name, field->value, field->str);
16682d156cdSTom Zanussi if (field->next)
16782d156cdSTom Zanussi define_flag_values(field->next, ev_name, field_name);
16882d156cdSTom Zanussi }
16982d156cdSTom Zanussi
define_flag_field(const char * ev_name,const char * field_name,const char * delim)17082d156cdSTom Zanussi static void define_flag_field(const char *ev_name,
17182d156cdSTom Zanussi const char *field_name,
17282d156cdSTom Zanussi const char *delim)
17382d156cdSTom Zanussi {
17482d156cdSTom Zanussi dSP;
17582d156cdSTom Zanussi
17682d156cdSTom Zanussi ENTER;
17782d156cdSTom Zanussi SAVETMPS;
17882d156cdSTom Zanussi PUSHMARK(SP);
17982d156cdSTom Zanussi
18082d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
18182d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
18282d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(delim, 0)));
18382d156cdSTom Zanussi
18482d156cdSTom Zanussi PUTBACK;
18582d156cdSTom Zanussi if (get_cv("main::define_flag_field", 0))
18682d156cdSTom Zanussi call_pv("main::define_flag_field", G_SCALAR);
18782d156cdSTom Zanussi SPAGAIN;
18882d156cdSTom Zanussi PUTBACK;
18982d156cdSTom Zanussi FREETMPS;
19082d156cdSTom Zanussi LEAVE;
19182d156cdSTom Zanussi }
19282d156cdSTom Zanussi
define_event_symbols(struct tep_event * event,const char * ev_name,struct tep_print_arg * args)19382d156cdSTom Zanussi static void define_event_symbols(struct tep_event *event,
19482d156cdSTom Zanussi const char *ev_name,
19597fbf3f0STzvetomir Stoyanov struct tep_print_arg *args)
19682d156cdSTom Zanussi {
1975647f94bSTzvetomir Stoyanov (VMware) if (args == NULL)
19882d156cdSTom Zanussi return;
1998579aca3STaeung Song
2008579aca3STaeung Song switch (args->type) {
2018579aca3STaeung Song case TEP_PRINT_NULL:
20282d156cdSTom Zanussi break;
2031e97216fSTzvetomir Stoyanov (VMware) case TEP_PRINT_ATOM:
20482d156cdSTom Zanussi define_flag_value(ev_name, cur_field_name, "0",
2051e97216fSTzvetomir Stoyanov (VMware) args->atom.atom);
20682d156cdSTom Zanussi zero_flag_atom = 0;
20782d156cdSTom Zanussi break;
20882d156cdSTom Zanussi case TEP_PRINT_FIELD:
20982d156cdSTom Zanussi free(cur_field_name);
2101e97216fSTzvetomir Stoyanov (VMware) cur_field_name = strdup(args->field.name);
21182d156cdSTom Zanussi break;
21282d156cdSTom Zanussi case TEP_PRINT_FLAGS:
21382d156cdSTom Zanussi define_event_symbols(event, ev_name, args->flags.field);
2141e97216fSTzvetomir Stoyanov (VMware) define_flag_field(ev_name, cur_field_name, args->flags.delim);
21582d156cdSTom Zanussi define_flag_values(args->flags.flags, ev_name, cur_field_name);
21682d156cdSTom Zanussi break;
21782d156cdSTom Zanussi case TEP_PRINT_SYMBOL:
21882d156cdSTom Zanussi define_event_symbols(event, ev_name, args->symbol.field);
2191e97216fSTzvetomir Stoyanov (VMware) define_symbolic_field(ev_name, cur_field_name);
22082d156cdSTom Zanussi define_symbolic_values(args->symbol.symbols, ev_name,
22182d156cdSTom Zanussi cur_field_name);
22282d156cdSTom Zanussi break;
22382d156cdSTom Zanussi case TEP_PRINT_HEX:
22482d156cdSTom Zanussi case TEP_PRINT_HEX_STR:
2251e97216fSTzvetomir Stoyanov (VMware) define_event_symbols(event, ev_name, args->hex.field);
2261e97216fSTzvetomir Stoyanov (VMware) define_event_symbols(event, ev_name, args->hex.size);
227e080e6f1SNamhyung Kim break;
228e080e6f1SNamhyung Kim case TEP_PRINT_INT_ARRAY:
229e080e6f1SNamhyung Kim define_event_symbols(event, ev_name, args->int_array.field);
2301e97216fSTzvetomir Stoyanov (VMware) define_event_symbols(event, ev_name, args->int_array.count);
231b839e1e8SJavi Merino define_event_symbols(event, ev_name, args->int_array.el_size);
232b839e1e8SJavi Merino break;
233b839e1e8SJavi Merino case TEP_PRINT_BSTRING:
234b839e1e8SJavi Merino case TEP_PRINT_DYNAMIC_ARRAY:
2351e97216fSTzvetomir Stoyanov (VMware) case TEP_PRINT_DYNAMIC_ARRAY_LEN:
2361e97216fSTzvetomir Stoyanov (VMware) case TEP_PRINT_STRING:
2371e97216fSTzvetomir Stoyanov (VMware) case TEP_PRINT_BITMASK:
2381e97216fSTzvetomir Stoyanov (VMware) break;
2391e97216fSTzvetomir Stoyanov (VMware) case TEP_PRINT_TYPE:
24082d156cdSTom Zanussi define_event_symbols(event, ev_name, args->typecast.item);
2411e97216fSTzvetomir Stoyanov (VMware) break;
24282d156cdSTom Zanussi case TEP_PRINT_OP:
24382d156cdSTom Zanussi if (strcmp(args->op.op, ":") == 0)
2441e97216fSTzvetomir Stoyanov (VMware) zero_flag_atom = 1;
24582d156cdSTom Zanussi define_event_symbols(event, ev_name, args->op.left);
24682d156cdSTom Zanussi define_event_symbols(event, ev_name, args->op.right);
24782d156cdSTom Zanussi break;
24882d156cdSTom Zanussi case TEP_PRINT_FUNC:
24982d156cdSTom Zanussi default:
2501e97216fSTzvetomir Stoyanov (VMware) pr_err("Unsupported print arg type\n");
25182d156cdSTom Zanussi /* we should warn... */
252e326e752SFrederic Weisbecker return;
25382d156cdSTom Zanussi }
25482d156cdSTom Zanussi
25582d156cdSTom Zanussi if (args->next)
25682d156cdSTom Zanussi define_event_symbols(event, ev_name, args->next);
25782d156cdSTom Zanussi }
25882d156cdSTom Zanussi
perl_process_callchain(struct perf_sample * sample,struct evsel * evsel,struct addr_location * al)25982d156cdSTom Zanussi static SV *perl_process_callchain(struct perf_sample *sample,
26082d156cdSTom Zanussi struct evsel *evsel,
261f7380c12SDima Kogan struct addr_location *al)
26232dcd021SJiri Olsa {
263f7380c12SDima Kogan struct callchain_cursor *cursor;
264f7380c12SDima Kogan AV *list;
265f7380c12SDima Kogan
266f7380c12SDima Kogan list = newAV();
267f7380c12SDima Kogan if (!list)
268f7380c12SDima Kogan goto exit;
269f7380c12SDima Kogan
270f7380c12SDima Kogan if (!symbol_conf.use_callchain || !sample->callchain)
271f7380c12SDima Kogan goto exit;
272f7380c12SDima Kogan
273f7380c12SDima Kogan cursor = get_tls_callchain_cursor();
27491d7b2deSArnaldo Carvalho de Melo
275fe176085SArnaldo Carvalho de Melo if (thread__resolve_callchain(al->thread, cursor, evsel,
276f7380c12SDima Kogan sample, NULL, NULL, scripting_max_stack) != 0) {
277f7380c12SDima Kogan pr_err("Failed to resolve callchain. Skipping\n");
278f7380c12SDima Kogan goto exit;
279f7380c12SDima Kogan }
280f7380c12SDima Kogan callchain_cursor_commit(cursor);
281f7380c12SDima Kogan
282f7380c12SDima Kogan
283f7380c12SDima Kogan while (1) {
284f7380c12SDima Kogan HV *elem;
285f7380c12SDima Kogan struct callchain_cursor_node *node;
286f7380c12SDima Kogan node = callchain_cursor_current(cursor);
287f7380c12SDima Kogan if (!node)
288f7380c12SDima Kogan break;
289f7380c12SDima Kogan
290f7380c12SDima Kogan elem = newHV();
291f7380c12SDima Kogan if (!elem)
292f7380c12SDima Kogan goto exit;
29376e20522SArnaldo Carvalho de Melo
29476e20522SArnaldo Carvalho de Melo if (!hv_stores(elem, "ip", newSVuv(node->ip))) {
29576e20522SArnaldo Carvalho de Melo hv_undef(elem);
29676e20522SArnaldo Carvalho de Melo goto exit;
297f7380c12SDima Kogan }
2985f0fef8aSArnaldo Carvalho de Melo
299f7380c12SDima Kogan if (node->ms.sym) {
30076e20522SArnaldo Carvalho de Melo HV *sym = newHV();
30176e20522SArnaldo Carvalho de Melo if (!sym) {
302f7380c12SDima Kogan hv_undef(elem);
30376e20522SArnaldo Carvalho de Melo goto exit;
3045f0fef8aSArnaldo Carvalho de Melo }
3055f0fef8aSArnaldo Carvalho de Melo if (!hv_stores(sym, "start", newSVuv(node->ms.sym->start)) ||
3065f0fef8aSArnaldo Carvalho de Melo !hv_stores(sym, "end", newSVuv(node->ms.sym->end)) ||
3075f0fef8aSArnaldo Carvalho de Melo !hv_stores(sym, "binding", newSVuv(node->ms.sym->binding)) ||
3085f0fef8aSArnaldo Carvalho de Melo !hv_stores(sym, "name", newSVpvn(node->ms.sym->name,
30976e20522SArnaldo Carvalho de Melo node->ms.sym->namelen)) ||
31076e20522SArnaldo Carvalho de Melo !hv_stores(elem, "sym", newRV_noinc((SV*)sym))) {
31176e20522SArnaldo Carvalho de Melo hv_undef(sym);
31276e20522SArnaldo Carvalho de Melo hv_undef(elem);
31376e20522SArnaldo Carvalho de Melo goto exit;
314f7380c12SDima Kogan }
315f7380c12SDima Kogan }
3165f0fef8aSArnaldo Carvalho de Melo
3175f0fef8aSArnaldo Carvalho de Melo if (node->ms.map) {
318*63df0e4bSIan Rogers struct map *map = node->ms.map;
319f7380c12SDima Kogan struct dso *dso = map ? map__dso(map) : NULL;
320*63df0e4bSIan Rogers const char *dsoname = "[unknown]";
321*63df0e4bSIan Rogers
322*63df0e4bSIan Rogers if (dso) {
323*63df0e4bSIan Rogers if (symbol_conf.show_kernel_path && dso->long_name)
3245eae7d84SArnaldo Carvalho de Melo dsoname = dso->long_name;
325*63df0e4bSIan Rogers else
326f7380c12SDima Kogan dsoname = dso->name;
32776e20522SArnaldo Carvalho de Melo }
32876e20522SArnaldo Carvalho de Melo if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) {
32976e20522SArnaldo Carvalho de Melo hv_undef(elem);
33076e20522SArnaldo Carvalho de Melo goto exit;
331f7380c12SDima Kogan }
332f7380c12SDima Kogan }
333f7380c12SDima Kogan
334f7380c12SDima Kogan callchain_cursor_advance(cursor);
335f7380c12SDima Kogan av_push(list, newRV_noinc((SV*)elem));
336f7380c12SDima Kogan }
337f7380c12SDima Kogan
338f7380c12SDima Kogan exit:
339f7380c12SDima Kogan return newRV_noinc((SV*)list);
340f7380c12SDima Kogan }
3418853a1b7SArnaldo Carvalho de Melo
perl_process_tracepoint(struct perf_sample * sample,struct evsel * evsel,struct addr_location * al)34232dcd021SJiri Olsa static void perl_process_tracepoint(struct perf_sample *sample,
343f7380c12SDima Kogan struct evsel *evsel,
34482d156cdSTom Zanussi struct addr_location *al)
345f7380c12SDima Kogan {
34697fbf3f0STzvetomir Stoyanov struct thread *thread = al->thread;
3472c92f982STzvetomir Stoyanov (VMware) struct tep_event *event = evsel->tp_format;
34882d156cdSTom Zanussi struct tep_format_field *field;
34982d156cdSTom Zanussi static char handler[256];
35082d156cdSTom Zanussi unsigned long long val;
35182d156cdSTom Zanussi unsigned long s, ns;
352be6d842aSDavid Ahern int pid;
353be6d842aSDavid Ahern int cpu = sample->cpu;
354be6d842aSDavid Ahern void *data = sample->raw_data;
355b9c5143aSFrederic Weisbecker unsigned long long nsecs = sample->time;
35682d156cdSTom Zanussi const char *comm = thread__comm_str(thread);
35782d156cdSTom Zanussi DECLARE_BITMAP(events_defined, TRACE_EVENT_TYPE_MAX);
35882d156cdSTom Zanussi
3591fc632ceSJiri Olsa bitmap_zero(events_defined, TRACE_EVENT_TYPE_MAX);
36037a058eaSRobert Richter dSP;
36137a058eaSRobert Richter
3620a87e7bcSArnaldo Carvalho de Melo if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
3631fc632ceSJiri Olsa return;
3640a87e7bcSArnaldo Carvalho de Melo
3650a87e7bcSArnaldo Carvalho de Melo if (!event) {
36682d156cdSTom Zanussi pr_debug("ug! no event found for type %" PRIu64, (u64)evsel->core.attr.config);
36797822433SArnaldo Carvalho de Melo return;
36882d156cdSTom Zanussi }
36982d156cdSTom Zanussi
37082d156cdSTom Zanussi pid = raw_field_value(event, "common_pid", data);
37149bd97c2SSean Christopherson
372cdae2d1eSJiri Olsa sprintf(handler, "%s::%s", event->system, event->name);
373cdae2d1eSJiri Olsa
374bd48c63eSArnaldo Carvalho de Melo if (!__test_and_set_bit(event->id, events_defined))
375bd48c63eSArnaldo Carvalho de Melo define_event_symbols(event, handler, event->print_fmt.args);
37682d156cdSTom Zanussi
37782d156cdSTom Zanussi s = nsecs / NSEC_PER_SEC;
37882d156cdSTom Zanussi ns = nsecs - s * NSEC_PER_SEC;
37982d156cdSTom Zanussi
38082d156cdSTom Zanussi ENTER;
38182d156cdSTom Zanussi SAVETMPS;
38282d156cdSTom Zanussi PUSHMARK(SP);
38382d156cdSTom Zanussi
38482d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(handler, 0)));
38582d156cdSTom Zanussi XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
38682d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVuv(cpu)));
38782d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVuv(s)));
388f7380c12SDima Kogan XPUSHs(sv_2mortal(newSVuv(ns)));
38982d156cdSTom Zanussi XPUSHs(sv_2mortal(newSViv(pid)));
39082d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(comm, 0)));
39182d156cdSTom Zanussi XPUSHs(sv_2mortal(perl_process_callchain(sample, evsel, al)));
39282d156cdSTom Zanussi
393bb39ccb2STzvetomir Stoyanov (VMware) /* common fields other than pid can be accessed via xsub fns */
39482d156cdSTom Zanussi
395bb39ccb2STzvetomir Stoyanov (VMware) for (field = event->format.fields; field; field = field->next) {
39682d156cdSTom Zanussi if (field->flags & TEP_FIELD_IS_STRING) {
39782d156cdSTom Zanussi int offset;
3981634bad3SIan Rogers if (field->flags & TEP_FIELD_IS_DYNAMIC) {
3997c689c83SMasami Hiramatsu offset = *(int *)(data + field->offset);
40082d156cdSTom Zanussi offset &= 0xffff;
40182d156cdSTom Zanussi if (tep_field_is_relative(field->flags))
40282d156cdSTom Zanussi offset += field->offset + field->size;
40382d156cdSTom Zanussi } else
40497822433SArnaldo Carvalho de Melo offset = field->offset;
405da378962SArnaldo Carvalho de Melo XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0)));
406bb39ccb2STzvetomir Stoyanov (VMware) } else { /* FIELD_IS_NUMERIC */
40782d156cdSTom Zanussi val = read_size(event, data + field->offset,
40882d156cdSTom Zanussi field->size);
40982d156cdSTom Zanussi if (field->flags & TEP_FIELD_IS_SIGNED) {
41082d156cdSTom Zanussi XPUSHs(sv_2mortal(newSViv(val)));
41182d156cdSTom Zanussi } else {
41282d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVuv(val)));
41382d156cdSTom Zanussi }
41482d156cdSTom Zanussi }
41582d156cdSTom Zanussi }
41682d156cdSTom Zanussi
41782d156cdSTom Zanussi PUTBACK;
41882d156cdSTom Zanussi
41982d156cdSTom Zanussi if (get_cv(handler, 0))
42082d156cdSTom Zanussi call_pv(handler, G_SCALAR);
42182d156cdSTom Zanussi else if (get_cv("main::trace_unhandled", 0)) {
42282d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(handler, 0)));
42382d156cdSTom Zanussi XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
42482d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVuv(cpu)));
425f7380c12SDima Kogan XPUSHs(sv_2mortal(newSVuv(nsecs)));
42682d156cdSTom Zanussi XPUSHs(sv_2mortal(newSViv(pid)));
42782d156cdSTom Zanussi XPUSHs(sv_2mortal(newSVpv(comm, 0)));
42882d156cdSTom Zanussi XPUSHs(sv_2mortal(perl_process_callchain(sample, evsel, al)));
42982d156cdSTom Zanussi call_pv("main::trace_unhandled", G_SCALAR);
43082d156cdSTom Zanussi }
43182d156cdSTom Zanussi SPAGAIN;
43282d156cdSTom Zanussi PUTBACK;
43382d156cdSTom Zanussi FREETMPS;
43497822433SArnaldo Carvalho de Melo LEAVE;
43537a058eaSRobert Richter }
43632dcd021SJiri Olsa
perl_process_event_generic(union perf_event * event,struct perf_sample * sample,struct evsel * evsel)43737a058eaSRobert Richter static void perl_process_event_generic(union perf_event *event,
43837a058eaSRobert Richter struct perf_sample *sample,
43937a058eaSRobert Richter struct evsel *evsel)
44037a058eaSRobert Richter {
44137a058eaSRobert Richter dSP;
44237a058eaSRobert Richter
44337a058eaSRobert Richter if (!get_cv("process_event", 0))
44437a058eaSRobert Richter return;
44537a058eaSRobert Richter
44697822433SArnaldo Carvalho de Melo ENTER;
4471fc632ceSJiri Olsa SAVETMPS;
44837a058eaSRobert Richter PUSHMARK(SP);
44937a058eaSRobert Richter XPUSHs(sv_2mortal(newSVpvn((const char *)event, event->header.size)));
45037a058eaSRobert Richter XPUSHs(sv_2mortal(newSVpvn((const char *)&evsel->core.attr, sizeof(evsel->core.attr))));
45137a058eaSRobert Richter XPUSHs(sv_2mortal(newSVpvn((const char *)sample, sizeof(*sample))));
45237a058eaSRobert Richter XPUSHs(sv_2mortal(newSVpvn((const char *)sample->raw_data, sample->raw_size)));
45337a058eaSRobert Richter PUTBACK;
45437a058eaSRobert Richter call_pv("process_event", G_SCALAR);
45537a058eaSRobert Richter SPAGAIN;
45637a058eaSRobert Richter PUTBACK;
45737a058eaSRobert Richter FREETMPS;
458da378962SArnaldo Carvalho de Melo LEAVE;
45937a058eaSRobert Richter }
46032dcd021SJiri Olsa
perl_process_event(union perf_event * event,struct perf_sample * sample,struct evsel * evsel,struct addr_location * al,struct addr_location * addr_al)4613f8e009eSAdrian Hunter static void perl_process_event(union perf_event *event,
462cac30400SAdrian Hunter struct perf_sample *sample,
46337a058eaSRobert Richter struct evsel *evsel,
464cac30400SAdrian Hunter struct addr_location *al,
465f7380c12SDima Kogan struct addr_location *addr_al)
4668853a1b7SArnaldo Carvalho de Melo {
46737a058eaSRobert Richter scripting_context__update(scripting_context, event, sample, evsel, al, addr_al);
46837a058eaSRobert Richter perl_process_tracepoint(sample, evsel, al);
46982d156cdSTom Zanussi perl_process_event_generic(event, sample, evsel);
47082d156cdSTom Zanussi }
47182d156cdSTom Zanussi
run_start_sub(void)47282d156cdSTom Zanussi static void run_start_sub(void)
47382d156cdSTom Zanussi {
47482d156cdSTom Zanussi dSP; /* access to Perl stack */
47582d156cdSTom Zanussi PUSHMARK(SP);
47682d156cdSTom Zanussi
47782d156cdSTom Zanussi if (get_cv("main::trace_begin", 0))
47882d156cdSTom Zanussi call_pv("main::trace_begin", G_DISCARD | G_NOARGS);
47982d156cdSTom Zanussi }
48082d156cdSTom Zanussi
48167e50ce0SAdrian Hunter /*
48267e50ce0SAdrian Hunter * Start trace script
48382d156cdSTom Zanussi */
perl_start_script(const char * script,int argc,const char ** argv,struct perf_session * session)48482d156cdSTom Zanussi static int perl_start_script(const char *script, int argc, const char **argv,
48582d156cdSTom Zanussi struct perf_session *session)
48682d156cdSTom Zanussi {
48767e50ce0SAdrian Hunter const char **command_line;
48867e50ce0SAdrian Hunter int i, err = 0;
48982d156cdSTom Zanussi
49082d156cdSTom Zanussi scripting_context->session = session;
49182d156cdSTom Zanussi
49282d156cdSTom Zanussi command_line = malloc((argc + 2) * sizeof(const char *));
49382d156cdSTom Zanussi command_line[0] = "";
49482d156cdSTom Zanussi command_line[1] = script;
49582d156cdSTom Zanussi for (i = 2; i < argc + 2; i++)
49682d156cdSTom Zanussi command_line[i] = argv[i - 2];
49782d156cdSTom Zanussi
49882d156cdSTom Zanussi my_perl = perl_alloc();
49982d156cdSTom Zanussi perl_construct(my_perl);
50082d156cdSTom Zanussi
50182d156cdSTom Zanussi if (perl_parse(my_perl, xs_init, argc + 2, (char **)command_line,
50282d156cdSTom Zanussi (char **)NULL)) {
50382d156cdSTom Zanussi err = -1;
50482d156cdSTom Zanussi goto error;
50582d156cdSTom Zanussi }
50682d156cdSTom Zanussi
50782d156cdSTom Zanussi if (perl_run(my_perl)) {
50882d156cdSTom Zanussi err = -1;
50982d156cdSTom Zanussi goto error;
51082d156cdSTom Zanussi }
51182d156cdSTom Zanussi
51282d156cdSTom Zanussi if (SvTRUE(ERRSV)) {
51382d156cdSTom Zanussi err = -1;
51482d156cdSTom Zanussi goto error;
51582d156cdSTom Zanussi }
51682d156cdSTom Zanussi
51782d156cdSTom Zanussi run_start_sub();
51882d156cdSTom Zanussi
51982d156cdSTom Zanussi free(command_line);
52082d156cdSTom Zanussi return 0;
52182d156cdSTom Zanussi error:
52282d156cdSTom Zanussi perl_free(my_perl);
52382d156cdSTom Zanussi free(command_line);
52482d156cdSTom Zanussi
525d445dd2aSAdrian Hunter return err;
526d445dd2aSAdrian Hunter }
527d445dd2aSAdrian Hunter
perl_flush_script(void)528d445dd2aSAdrian Hunter static int perl_flush_script(void)
529d445dd2aSAdrian Hunter {
53082d156cdSTom Zanussi return 0;
53182d156cdSTom Zanussi }
53282d156cdSTom Zanussi
53382d156cdSTom Zanussi /*
53482d156cdSTom Zanussi * Stop trace script
53582d156cdSTom Zanussi */
perl_stop_script(void)53682d156cdSTom Zanussi static int perl_stop_script(void)
53782d156cdSTom Zanussi {
53882d156cdSTom Zanussi dSP; /* access to Perl stack */
53982d156cdSTom Zanussi PUSHMARK(SP);
54082d156cdSTom Zanussi
54182d156cdSTom Zanussi if (get_cv("main::trace_end", 0))
54282d156cdSTom Zanussi call_pv("main::trace_end", G_DISCARD | G_NOARGS);
54382d156cdSTom Zanussi
54482d156cdSTom Zanussi perl_destruct(my_perl);
54582d156cdSTom Zanussi perl_free(my_perl);
54682d156cdSTom Zanussi
547096177a8STzvetomir Stoyanov (VMware) return 0;
54882d156cdSTom Zanussi }
549a5e05abcSSteven Rostedt (VMware)
perl_generate_script(struct tep_handle * pevent,const char * outfile)550a5e05abcSSteven Rostedt (VMware) static int perl_generate_script(struct tep_handle *pevent, const char *outfile)
55197fbf3f0STzvetomir Stoyanov {
5522c92f982STzvetomir Stoyanov (VMware) int i, not_first, count, nr_events;
55382d156cdSTom Zanussi struct tep_event **all_events;
55482d156cdSTom Zanussi struct tep_event *event = NULL;
55582d156cdSTom Zanussi struct tep_format_field *f;
55682d156cdSTom Zanussi char fname[PATH_MAX];
55782d156cdSTom Zanussi FILE *ofp;
55882d156cdSTom Zanussi
55982d156cdSTom Zanussi sprintf(fname, "%s.pl", outfile);
56082d156cdSTom Zanussi ofp = fopen(fname, "w");
56182d156cdSTom Zanussi if (ofp == NULL) {
56282d156cdSTom Zanussi fprintf(stderr, "couldn't open %s\n", fname);
563133dc4c3SIngo Molnar return -1;
564133dc4c3SIngo Molnar }
56582d156cdSTom Zanussi
56682d156cdSTom Zanussi fprintf(ofp, "# perf script event handlers, "
56782d156cdSTom Zanussi "generated by perf script -g perl\n");
56882d156cdSTom Zanussi
56982d156cdSTom Zanussi fprintf(ofp, "# Licensed under the terms of the GNU GPL"
57082d156cdSTom Zanussi " License version 2\n\n");
57182d156cdSTom Zanussi
57282d156cdSTom Zanussi fprintf(ofp, "# The common_* event handler fields are the most useful "
57382d156cdSTom Zanussi "fields common to\n");
57482d156cdSTom Zanussi
57582d156cdSTom Zanussi fprintf(ofp, "# all events. They don't necessarily correspond to "
57682d156cdSTom Zanussi "the 'common_*' fields\n");
57782d156cdSTom Zanussi
57882d156cdSTom Zanussi fprintf(ofp, "# in the format files. Those fields not available as "
57982d156cdSTom Zanussi "handler params can\n");
58082d156cdSTom Zanussi
58182d156cdSTom Zanussi fprintf(ofp, "# be retrieved using Perl functions of the form "
58282d156cdSTom Zanussi "common_*($context).\n");
58382d156cdSTom Zanussi
58482d156cdSTom Zanussi fprintf(ofp, "# See Context.pm for the list of available "
58582d156cdSTom Zanussi "functions.\n\n");
58682d156cdSTom Zanussi
58782d156cdSTom Zanussi fprintf(ofp, "use lib \"$ENV{'PERF_EXEC_PATH'}/scripts/perl/"
58882d156cdSTom Zanussi "Perf-Trace-Util/lib\";\n");
58982d156cdSTom Zanussi
59082d156cdSTom Zanussi fprintf(ofp, "use lib \"./Perf-Trace-Util/lib\";\n");
59182d156cdSTom Zanussi fprintf(ofp, "use Perf::Trace::Core;\n");
59282d156cdSTom Zanussi fprintf(ofp, "use Perf::Trace::Context;\n");
593f7380c12SDima Kogan fprintf(ofp, "use Perf::Trace::Util;\n\n");
594f7380c12SDima Kogan
595f7380c12SDima Kogan fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n");
596f7380c12SDima Kogan fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n");
597f7380c12SDima Kogan
598f7380c12SDima Kogan
599f7380c12SDima Kogan fprintf(ofp, "\n\
600f7380c12SDima Kogan sub print_backtrace\n\
601f7380c12SDima Kogan {\n\
602f7380c12SDima Kogan my $callchain = shift;\n\
603f7380c12SDima Kogan for my $node (@$callchain)\n\
604f7380c12SDima Kogan {\n\
605f7380c12SDima Kogan if(exists $node->{sym})\n\
606f7380c12SDima Kogan {\n\
607f7380c12SDima Kogan printf( \"\\t[\\%%x] \\%%s\\n\", $node->{ip}, $node->{sym}{name});\n\
608f7380c12SDima Kogan }\n\
609f7380c12SDima Kogan else\n\
610f7380c12SDima Kogan {\n\
611f7380c12SDima Kogan printf( \"\\t[\\%%x]\\n\", $node{ip});\n\
612f7380c12SDima Kogan }\n\
613f7380c12SDima Kogan }\n\
614a5e05abcSSteven Rostedt (VMware) }\n\n\
615a5e05abcSSteven Rostedt (VMware) ");
61682d156cdSTom Zanussi
617a5e05abcSSteven Rostedt (VMware) nr_events = tep_get_events_count(pevent);
618a5e05abcSSteven Rostedt (VMware) all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
61982d156cdSTom Zanussi
62082d156cdSTom Zanussi for (i = 0; all_events && i < nr_events; i++) {
62182d156cdSTom Zanussi event = all_events[i];
62282d156cdSTom Zanussi fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
62382d156cdSTom Zanussi fprintf(ofp, "\tmy (");
62482d156cdSTom Zanussi
62582d156cdSTom Zanussi fprintf(ofp, "$event_name, ");
62682d156cdSTom Zanussi fprintf(ofp, "$context, ");
62782d156cdSTom Zanussi fprintf(ofp, "$common_cpu, ");
628f7380c12SDima Kogan fprintf(ofp, "$common_secs, ");
629f7380c12SDima Kogan fprintf(ofp, "$common_nsecs,\n");
63082d156cdSTom Zanussi fprintf(ofp, "\t $common_pid, ");
63182d156cdSTom Zanussi fprintf(ofp, "$common_comm, ");
63282d156cdSTom Zanussi fprintf(ofp, "$common_callchain,\n\t ");
63382d156cdSTom Zanussi
63482d156cdSTom Zanussi not_first = 0;
63582d156cdSTom Zanussi count = 0;
63682d156cdSTom Zanussi
63782d156cdSTom Zanussi for (f = event->format.fields; f; f = f->next) {
63882d156cdSTom Zanussi if (not_first++)
63982d156cdSTom Zanussi fprintf(ofp, ", ");
64082d156cdSTom Zanussi if (++count % 5 == 0)
64182d156cdSTom Zanussi fprintf(ofp, "\n\t ");
64282d156cdSTom Zanussi
64382d156cdSTom Zanussi fprintf(ofp, "$%s", f->name);
64482d156cdSTom Zanussi }
64582d156cdSTom Zanussi fprintf(ofp, ") = @_;\n\n");
646f7380c12SDima Kogan
64782d156cdSTom Zanussi fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
64882d156cdSTom Zanussi "$common_secs, $common_nsecs,\n\t "
64982d156cdSTom Zanussi "$common_pid, $common_comm, $common_callchain);\n\n");
65082d156cdSTom Zanussi
65182d156cdSTom Zanussi fprintf(ofp, "\tprintf(\"");
65282d156cdSTom Zanussi
65382d156cdSTom Zanussi not_first = 0;
65482d156cdSTom Zanussi count = 0;
65582d156cdSTom Zanussi
65682d156cdSTom Zanussi for (f = event->format.fields; f; f = f->next) {
65782d156cdSTom Zanussi if (not_first++)
65882d156cdSTom Zanussi fprintf(ofp, ", ");
65982d156cdSTom Zanussi if (count && count % 4 == 0) {
66082d156cdSTom Zanussi fprintf(ofp, "\".\n\t \"");
66182d156cdSTom Zanussi }
662bb39ccb2STzvetomir Stoyanov (VMware) count++;
663bb39ccb2STzvetomir Stoyanov (VMware)
664bb39ccb2STzvetomir Stoyanov (VMware) fprintf(ofp, "%s=", f->name);
66582d156cdSTom Zanussi if (f->flags & TEP_FIELD_IS_STRING ||
666bb39ccb2STzvetomir Stoyanov (VMware) f->flags & TEP_FIELD_IS_FLAG ||
66782d156cdSTom Zanussi f->flags & TEP_FIELD_IS_SYMBOLIC)
66882d156cdSTom Zanussi fprintf(ofp, "%%s");
66982d156cdSTom Zanussi else if (f->flags & TEP_FIELD_IS_SIGNED)
67082d156cdSTom Zanussi fprintf(ofp, "%%d");
67182d156cdSTom Zanussi else
67282d156cdSTom Zanussi fprintf(ofp, "%%u");
67382d156cdSTom Zanussi }
67482d156cdSTom Zanussi
67582d156cdSTom Zanussi fprintf(ofp, "\\n\",\n\t ");
67682d156cdSTom Zanussi
67782d156cdSTom Zanussi not_first = 0;
67882d156cdSTom Zanussi count = 0;
67982d156cdSTom Zanussi
68082d156cdSTom Zanussi for (f = event->format.fields; f; f = f->next) {
68182d156cdSTom Zanussi if (not_first++)
68282d156cdSTom Zanussi fprintf(ofp, ", ");
68382d156cdSTom Zanussi
684bb39ccb2STzvetomir Stoyanov (VMware) if (++count % 5 == 0)
68582d156cdSTom Zanussi fprintf(ofp, "\n\t ");
68682d156cdSTom Zanussi
68782d156cdSTom Zanussi if (f->flags & TEP_FIELD_IS_FLAG) {
68882d156cdSTom Zanussi if ((count - 1) % 5 != 0) {
68982d156cdSTom Zanussi fprintf(ofp, "\n\t ");
69082d156cdSTom Zanussi count = 4;
69182d156cdSTom Zanussi }
69282d156cdSTom Zanussi fprintf(ofp, "flag_str(\"");
69382d156cdSTom Zanussi fprintf(ofp, "%s::%s\", ", event->system,
694bb39ccb2STzvetomir Stoyanov (VMware) event->name);
69582d156cdSTom Zanussi fprintf(ofp, "\"%s\", $%s)", f->name,
69682d156cdSTom Zanussi f->name);
69782d156cdSTom Zanussi } else if (f->flags & TEP_FIELD_IS_SYMBOLIC) {
69882d156cdSTom Zanussi if ((count - 1) % 5 != 0) {
69982d156cdSTom Zanussi fprintf(ofp, "\n\t ");
70082d156cdSTom Zanussi count = 4;
70182d156cdSTom Zanussi }
70282d156cdSTom Zanussi fprintf(ofp, "symbol_str(\"");
70382d156cdSTom Zanussi fprintf(ofp, "%s::%s\", ", event->system,
70482d156cdSTom Zanussi event->name);
70582d156cdSTom Zanussi fprintf(ofp, "\"%s\", $%s)", f->name,
70682d156cdSTom Zanussi f->name);
70782d156cdSTom Zanussi } else
708f7380c12SDima Kogan fprintf(ofp, "$%s", f->name);
709f7380c12SDima Kogan }
710f7380c12SDima Kogan
711f7380c12SDima Kogan fprintf(ofp, ");\n\n");
71282d156cdSTom Zanussi
71382d156cdSTom Zanussi fprintf(ofp, "\tprint_backtrace($common_callchain);\n");
71482d156cdSTom Zanussi
71582d156cdSTom Zanussi fprintf(ofp, "}\n\n");
71682d156cdSTom Zanussi }
717f7380c12SDima Kogan
71882d156cdSTom Zanussi fprintf(ofp, "sub trace_unhandled\n{\n\tmy ($event_name, $context, "
71982d156cdSTom Zanussi "$common_cpu, $common_secs, $common_nsecs,\n\t "
72082d156cdSTom Zanussi "$common_pid, $common_comm, $common_callchain) = @_;\n\n");
721f7380c12SDima Kogan
722f7380c12SDima Kogan fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
723f7380c12SDima Kogan "$common_secs, $common_nsecs,\n\t $common_pid, "
72482d156cdSTom Zanussi "$common_comm, $common_callchain);\n");
72582d156cdSTom Zanussi fprintf(ofp, "\tprint_backtrace($common_callchain);\n");
72682d156cdSTom Zanussi fprintf(ofp, "}\n\n");
72782d156cdSTom Zanussi
72837a058eaSRobert Richter fprintf(ofp, "sub print_header\n{\n"
72937a058eaSRobert Richter "\tmy ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;\n\n"
73037a058eaSRobert Richter "\tprintf(\"%%-20s %%5u %%05u.%%09u %%8u %%-20s \",\n\t "
73137a058eaSRobert Richter "$event_name, $cpu, $secs, $nsecs, $pid, $comm);\n}\n");
73237a058eaSRobert Richter
73337a058eaSRobert Richter fprintf(ofp,
73437a058eaSRobert Richter "\n# Packed byte string args of process_event():\n"
73537a058eaSRobert Richter "#\n"
73637a058eaSRobert Richter "# $event:\tunion perf_event\tutil/event.h\n"
73737a058eaSRobert Richter "# $attr:\tstruct perf_event_attr\tlinux/perf_event.h\n"
73837a058eaSRobert Richter "# $sample:\tstruct perf_sample\tutil/event.h\n"
73937a058eaSRobert Richter "# $raw_data:\tperf_sample->raw_data\tutil/event.h\n"
74037a058eaSRobert Richter "\n"
74137a058eaSRobert Richter "sub process_event\n"
74237a058eaSRobert Richter "{\n"
74337a058eaSRobert Richter "\tmy ($event, $attr, $sample, $raw_data) = @_;\n"
74437a058eaSRobert Richter "\n"
74537a058eaSRobert Richter "\tmy @event\t= unpack(\"LSS\", $event);\n"
74637a058eaSRobert Richter "\tmy @attr\t= unpack(\"LLQQQQQLLQQ\", $attr);\n"
74737a058eaSRobert Richter "\tmy @sample\t= unpack(\"QLLQQQQQLL\", $sample);\n"
74837a058eaSRobert Richter "\tmy @raw_data\t= unpack(\"C*\", $raw_data);\n"
74937a058eaSRobert Richter "\n"
75082d156cdSTom Zanussi "\tuse Data::Dumper;\n"
75182d156cdSTom Zanussi "\tprint Dumper \\@event, \\@attr, \\@sample, \\@raw_data;\n"
75282d156cdSTom Zanussi "}\n");
75382d156cdSTom Zanussi
75482d156cdSTom Zanussi fclose(ofp);
75582d156cdSTom Zanussi
75682d156cdSTom Zanussi fprintf(stderr, "generated Perl script: %s\n", fname);
75782d156cdSTom Zanussi
75882d156cdSTom Zanussi return 0;
75982d156cdSTom Zanussi }
7606ea4b5dbSAdrian Hunter
76182d156cdSTom Zanussi struct scripting_ops perl_scripting_ops = {
762d445dd2aSAdrian Hunter .name = "Perl",
76382d156cdSTom Zanussi .dirname = "perl",
76482d156cdSTom Zanussi .start_script = perl_start_script,
76582d156cdSTom Zanussi .flush_script = perl_flush_script,
76682d156cdSTom Zanussi .stop_script = perl_stop_script,
767 .process_event = perl_process_event,
768 .generate_script = perl_generate_script,
769 };
770