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