1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * trace-event-perl.  Feed perf script events to an embedded Perl interpreter.
3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  This program is free software; you can redistribute it and/or modify
7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  it under the terms of the GNU General Public License as published by
8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  the Free Software Foundation; either version 2 of the License, or
9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  (at your option) any later version.
10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  This program is distributed in the hope that it will be useful,
12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  GNU General Public License for more details.
15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  You should have received a copy of the GNU General Public License
17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  along with this program; if not, write to the Free Software
18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdio.h>
23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdlib.h>
24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <string.h>
25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <ctype.h>
26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <errno.h>
27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../util.h"
29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <EXTERN.h>
30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <perl.h>
31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../../perf.h"
33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../thread.h"
34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../event.h"
35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../trace-event.h"
36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../evsel.h"
37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid boot_Perf__Trace__Context(pTHX_ CV *cv);
39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid boot_DynaLoader(pTHX_ CV *cv);
40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtypedef PerlInterpreter * INTERP;
41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid xs_init(pTHX);
43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid xs_init(pTHX)
45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *file = __FILE__;
47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	dXSUB_SYS;
48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	newXS("Perf::Trace::Context::bootstrap", boot_Perf__Trace__Context,
50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	      file);
51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengINTERP my_perl;
55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define FTRACE_MAX_EVENT				\
57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	((1 << (sizeof(unsigned short) * 8)) - 1)
58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct event_format *events[FTRACE_MAX_EVENT];
60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengextern struct scripting_context *scripting_context;
62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char *cur_field_name;
64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int zero_flag_atom;
65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void define_symbolic_value(const char *ev_name,
67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  const char *field_name,
68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  const char *field_value,
69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  const char *field_str)
70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long value;
72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	dSP;
73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	value = eval_flag(field_value);
75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ENTER;
77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SAVETMPS;
78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUSHMARK(SP);
79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVuv(value)));
83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(field_str, 0)));
84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (get_cv("main::define_symbolic_value", 0))
87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		call_pv("main::define_symbolic_value", G_SCALAR);
88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SPAGAIN;
89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	FREETMPS;
91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	LEAVE;
92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void define_symbolic_values(struct print_flag_sym *field,
95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   const char *ev_name,
96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   const char *field_name)
97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	define_symbolic_value(ev_name, field_name, field->value, field->str);
99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (field->next)
100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_symbolic_values(field->next, ev_name, field_name);
101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void define_symbolic_field(const char *ev_name,
104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  const char *field_name)
105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	dSP;
107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ENTER;
109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SAVETMPS;
110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUSHMARK(SP);
111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (get_cv("main::define_symbolic_field", 0))
117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		call_pv("main::define_symbolic_field", G_SCALAR);
118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SPAGAIN;
119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	FREETMPS;
121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	LEAVE;
122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void define_flag_value(const char *ev_name,
125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      const char *field_name,
126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      const char *field_value,
127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      const char *field_str)
128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long value;
130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	dSP;
131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	value = eval_flag(field_value);
133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ENTER;
135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SAVETMPS;
136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUSHMARK(SP);
137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVuv(value)));
141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(field_str, 0)));
142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (get_cv("main::define_flag_value", 0))
145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		call_pv("main::define_flag_value", G_SCALAR);
146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SPAGAIN;
147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	FREETMPS;
149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	LEAVE;
150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void define_flag_values(struct print_flag_sym *field,
153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       const char *ev_name,
154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       const char *field_name)
155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	define_flag_value(ev_name, field_name, field->value, field->str);
157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (field->next)
158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_flag_values(field->next, ev_name, field_name);
159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void define_flag_field(const char *ev_name,
162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      const char *field_name,
163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      const char *delim)
164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	dSP;
166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ENTER;
168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SAVETMPS;
169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUSHMARK(SP);
170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(delim, 0)));
174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (get_cv("main::define_flag_field", 0))
177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		call_pv("main::define_flag_field", G_SCALAR);
178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SPAGAIN;
179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	FREETMPS;
181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	LEAVE;
182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void define_event_symbols(struct event_format *event,
185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 const char *ev_name,
186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 struct print_arg *args)
187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (args->type) {
189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_NULL:
190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_ATOM:
192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_flag_value(ev_name, cur_field_name, "0",
193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  args->atom.atom);
194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		zero_flag_atom = 0;
195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FIELD:
197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (cur_field_name)
198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(cur_field_name);
199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		cur_field_name = strdup(args->field.name);
200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FLAGS:
202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_event_symbols(event, ev_name, args->flags.field);
203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_flag_field(ev_name, cur_field_name, args->flags.delim);
204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_flag_values(args->flags.flags, ev_name, cur_field_name);
205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_SYMBOL:
207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_event_symbols(event, ev_name, args->symbol.field);
208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_symbolic_field(ev_name, cur_field_name);
209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_symbolic_values(args->symbol.symbols, ev_name,
210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				       cur_field_name);
211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_HEX:
213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_event_symbols(event, ev_name, args->hex.field);
214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_event_symbols(event, ev_name, args->hex.size);
215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_BSTRING:
217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_DYNAMIC_ARRAY:
218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_STRING:
219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_TYPE:
221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_event_symbols(event, ev_name, args->typecast.item);
222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_OP:
224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(args->op.op, ":") == 0)
225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			zero_flag_atom = 1;
226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_event_symbols(event, ev_name, args->op.left);
227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_event_symbols(event, ev_name, args->op.right);
228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FUNC:
230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_err("Unsupported print arg type\n");
232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* we should warn... */
233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (args->next)
237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		define_event_symbols(event, ev_name, args->next);
238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic inline struct event_format *find_cache_event(struct perf_evsel *evsel)
241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char ev_name[256];
243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *event;
244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int type = evsel->attr.config;
245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (events[type])
247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return events[type];
248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	events[type] = event = evsel->tp_format;
250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event)
251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sprintf(ev_name, "%s::%s", event->system, event->name);
254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	define_event_symbols(event, ev_name, event->print_fmt.args);
256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return event;
258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				    struct perf_sample *sample,
262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				    struct perf_evsel *evsel,
263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				    struct machine *machine __maybe_unused,
264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				    struct thread *thread,
265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					struct addr_location *al)
266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char handler[256];
269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long val;
270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long s, ns;
271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *event;
272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int pid;
273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int cpu = sample->cpu;
274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	void *data = sample->raw_data;
275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long nsecs = sample->time;
276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *comm = thread->comm;
277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	dSP;
279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event = find_cache_event(evsel);
284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event)
285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		die("ug! no event found for type %" PRIu64, (u64)evsel->attr.config);
286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pid = raw_field_value(event, "common_pid", data);
288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sprintf(handler, "%s::%s", event->system, event->name);
290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	s = nsecs / NSECS_PER_SEC;
292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ns = nsecs - s * NSECS_PER_SEC;
293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	scripting_context->event_data = data;
295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	scripting_context->pevent = evsel->tp_format->pevent;
296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ENTER;
298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SAVETMPS;
299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUSHMARK(SP);
300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(handler, 0)));
302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVuv(cpu)));
304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVuv(s)));
305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVuv(ns)));
306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSViv(pid)));
307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpv(comm, 0)));
308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* common fields other than pid can be accessed via xsub fns */
310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (field = event->format.fields; field; field = field->next) {
312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (field->flags & FIELD_IS_STRING) {
313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			int offset;
314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (field->flags & FIELD_IS_DYNAMIC) {
315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				offset = *(int *)(data + field->offset);
316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				offset &= 0xffff;
317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} else
318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				offset = field->offset;
319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0)));
320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else { /* FIELD_IS_NUMERIC */
321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			val = read_size(event, data + field->offset,
322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					field->size);
323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (field->flags & FIELD_IS_SIGNED) {
324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				XPUSHs(sv_2mortal(newSViv(val)));
325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} else {
326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				XPUSHs(sv_2mortal(newSVuv(val)));
327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (get_cv(handler, 0))
334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		call_pv(handler, G_SCALAR);
335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	else if (get_cv("main::trace_unhandled", 0)) {
336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		XPUSHs(sv_2mortal(newSVpv(handler, 0)));
337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		XPUSHs(sv_2mortal(newSVuv(cpu)));
339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		XPUSHs(sv_2mortal(newSVuv(nsecs)));
340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		XPUSHs(sv_2mortal(newSViv(pid)));
341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		XPUSHs(sv_2mortal(newSVpv(comm, 0)));
342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		call_pv("main::trace_unhandled", G_SCALAR);
343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SPAGAIN;
345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	FREETMPS;
347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	LEAVE;
348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perl_process_event_generic(union perf_event *event,
351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				       struct perf_sample *sample,
352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				       struct perf_evsel *evsel,
353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				       struct machine *machine __maybe_unused,
354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				       struct thread *thread __maybe_unused,
355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					   struct addr_location *al __maybe_unused)
356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	dSP;
358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!get_cv("process_event", 0))
360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ENTER;
363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SAVETMPS;
364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUSHMARK(SP);
365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpvn((const char *)event, event->header.size)));
366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpvn((const char *)&evsel->attr, sizeof(evsel->attr))));
367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpvn((const char *)sample, sizeof(*sample))));
368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	XPUSHs(sv_2mortal(newSVpvn((const char *)sample->raw_data, sample->raw_size)));
369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	call_pv("process_event", G_SCALAR);
371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	SPAGAIN;
372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUTBACK;
373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	FREETMPS;
374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	LEAVE;
375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perl_process_event(union perf_event *event,
378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       struct perf_sample *sample,
379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       struct perf_evsel *evsel,
380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       struct machine *machine,
381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       struct thread *thread,
382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   struct addr_location *al)
383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perl_process_tracepoint(event, sample, evsel, machine, thread, al);
385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perl_process_event_generic(event, sample, evsel, machine, thread, al);
386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void run_start_sub(void)
389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	dSP; /* access to Perl stack */
391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUSHMARK(SP);
392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (get_cv("main::trace_begin", 0))
394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		call_pv("main::trace_begin", G_DISCARD | G_NOARGS);
395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Start trace script
399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int perl_start_script(const char *script, int argc, const char **argv)
401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char **command_line;
403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i, err = 0;
404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	command_line = malloc((argc + 2) * sizeof(const char *));
406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	command_line[0] = "";
407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	command_line[1] = script;
408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 2; i < argc + 2; i++)
409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		command_line[i] = argv[i - 2];
410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	my_perl = perl_alloc();
412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perl_construct(my_perl);
413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (perl_parse(my_perl, xs_init, argc + 2, (char **)command_line,
415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       (char **)NULL)) {
416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		err = -1;
417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto error;
418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (perl_run(my_perl)) {
421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		err = -1;
422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto error;
423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (SvTRUE(ERRSV)) {
426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		err = -1;
427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto error;
428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	run_start_sub();
431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(command_line);
433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengerror:
435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perl_free(my_perl);
436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(command_line);
437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return err;
439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Stop trace script
443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int perl_stop_script(void)
445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	dSP; /* access to Perl stack */
447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PUSHMARK(SP);
448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (get_cv("main::trace_end", 0))
450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		call_pv("main::trace_end", G_DISCARD | G_NOARGS);
451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perl_destruct(my_perl);
453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perl_free(my_perl);
454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int perl_generate_script(struct pevent *pevent, const char *outfile)
459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *event = NULL;
461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *f;
462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char fname[PATH_MAX];
463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int not_first, count;
464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	FILE *ofp;
465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sprintf(fname, "%s.pl", outfile);
467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ofp = fopen(fname, "w");
468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ofp == NULL) {
469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(stderr, "couldn't open %s\n", fname);
470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
471e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
472e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
473e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "# perf script event handlers, "
474e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"generated by perf script -g perl\n");
475e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
476e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "# Licensed under the terms of the GNU GPL"
477e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		" License version 2\n\n");
478e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
479e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "# The common_* event handler fields are the most useful "
480e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"fields common to\n");
481e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
482e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "# all events.  They don't necessarily correspond to "
483e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"the 'common_*' fields\n");
484e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
485e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "# in the format files.  Those fields not available as "
486e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"handler params can\n");
487e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
488e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "# be retrieved using Perl functions of the form "
489e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"common_*($context).\n");
490e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
491e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "# See Context.pm for the list of available "
492e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"functions.\n\n");
493e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
494e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "use lib \"$ENV{'PERF_EXEC_PATH'}/scripts/perl/"
495e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"Perf-Trace-Util/lib\";\n");
496e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
497e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "use lib \"./Perf-Trace-Util/lib\";\n");
498e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "use Perf::Trace::Core;\n");
499e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "use Perf::Trace::Context;\n");
500e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "use Perf::Trace::Util;\n\n");
501e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
502e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n");
503e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n");
504e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
505e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while ((event = trace_find_next_event(pevent, event))) {
506e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
507e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "\tmy (");
508e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
509e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "$event_name, ");
510e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "$context, ");
511e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "$common_cpu, ");
512e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "$common_secs, ");
513e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "$common_nsecs,\n");
514e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "\t    $common_pid, ");
515e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "$common_comm,\n\t    ");
516e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
517e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		not_first = 0;
518e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		count = 0;
519e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
520e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (f = event->format.fields; f; f = f->next) {
521e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (not_first++)
522e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, ", ");
523e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (++count % 5 == 0)
524e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "\n\t    ");
525e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
526e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			fprintf(ofp, "$%s", f->name);
527e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
528e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, ") = @_;\n\n");
529e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
530e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
531e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			"$common_secs, $common_nsecs,\n\t             "
532e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			"$common_pid, $common_comm);\n\n");
533e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
534e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "\tprintf(\"");
535e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
536e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		not_first = 0;
537e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		count = 0;
538e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
539e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (f = event->format.fields; f; f = f->next) {
540e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (not_first++)
541e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, ", ");
542e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (count && count % 4 == 0) {
543e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "\".\n\t       \"");
544e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
545e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			count++;
546e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
547e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			fprintf(ofp, "%s=", f->name);
548e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (f->flags & FIELD_IS_STRING ||
549e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			    f->flags & FIELD_IS_FLAG ||
550e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			    f->flags & FIELD_IS_SYMBOLIC)
551e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "%%s");
552e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else if (f->flags & FIELD_IS_SIGNED)
553e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "%%d");
554e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
555e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "%%u");
556e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
557e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
558e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "\\n\",\n\t       ");
559e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
560e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		not_first = 0;
561e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		count = 0;
562e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
563e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (f = event->format.fields; f; f = f->next) {
564e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (not_first++)
565e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, ", ");
566e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
567e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (++count % 5 == 0)
568e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "\n\t       ");
569e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
570e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (f->flags & FIELD_IS_FLAG) {
571e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if ((count - 1) % 5 != 0) {
572e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					fprintf(ofp, "\n\t       ");
573e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					count = 4;
574e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
575e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "flag_str(\"");
576e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "%s::%s\", ", event->system,
577e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					event->name);
578e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "\"%s\", $%s)", f->name,
579e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					f->name);
580e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} else if (f->flags & FIELD_IS_SYMBOLIC) {
581e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if ((count - 1) % 5 != 0) {
582e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					fprintf(ofp, "\n\t       ");
583e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					count = 4;
584e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
585e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "symbol_str(\"");
586e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "%s::%s\", ", event->system,
587e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					event->name);
588e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "\"%s\", $%s)", f->name,
589e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					f->name);
590e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} else
591e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				fprintf(ofp, "$%s", f->name);
592e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
593e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
594e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, ");\n");
595e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(ofp, "}\n\n");
596e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
597e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
598e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "sub trace_unhandled\n{\n\tmy ($event_name, $context, "
599e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"$common_cpu, $common_secs, $common_nsecs,\n\t    "
600e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"$common_pid, $common_comm) = @_;\n\n");
601e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
602e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
603e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"$common_secs, $common_nsecs,\n\t             $common_pid, "
604e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"$common_comm);\n}\n\n");
605e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
606e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp, "sub print_header\n{\n"
607e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\tmy ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;\n\n"
608e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\tprintf(\"%%-20s %%5u %%05u.%%09u %%8u %%-20s \",\n\t       "
609e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"$event_name, $cpu, $secs, $nsecs, $pid, $comm);\n}\n");
610e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
611e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(ofp,
612e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\n# Packed byte string args of process_event():\n"
613e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"#\n"
614e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"# $event:\tunion perf_event\tutil/event.h\n"
615e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"# $attr:\tstruct perf_event_attr\tlinux/perf_event.h\n"
616e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"# $sample:\tstruct perf_sample\tutil/event.h\n"
617e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"# $raw_data:\tperf_sample->raw_data\tutil/event.h\n"
618e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\n"
619e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"sub process_event\n"
620e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"{\n"
621e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\tmy ($event, $attr, $sample, $raw_data) = @_;\n"
622e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\n"
623e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\tmy @event\t= unpack(\"LSS\", $event);\n"
624e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\tmy @attr\t= unpack(\"LLQQQQQLLQQ\", $attr);\n"
625e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\tmy @sample\t= unpack(\"QLLQQQQQLL\", $sample);\n"
626e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\tmy @raw_data\t= unpack(\"C*\", $raw_data);\n"
627e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\n"
628e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\tuse Data::Dumper;\n"
629e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"\tprint Dumper \\@event, \\@attr, \\@sample, \\@raw_data;\n"
630e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"}\n");
631e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
632e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fclose(ofp);
633e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
634e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fprintf(stderr, "generated Perl script: %s\n", fname);
635e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
636e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
637e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
638e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
639e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct scripting_ops perl_scripting_ops = {
640e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.name = "Perl",
641e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.start_script = perl_start_script,
642e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.stop_script = perl_stop_script,
643e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.process_event = perl_process_event,
644e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.generate_script = perl_generate_script,
645e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
646