xref: /openbmc/linux/tools/perf/util/scripting-engines/trace-event-perl.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
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