1*58e6ee5fSAndroid Build Coastguard Worker // tracecmd.i 2*58e6ee5fSAndroid Build Coastguard Worker %module ctracecmd 3*58e6ee5fSAndroid Build Coastguard Worker %include "typemaps.i" 4*58e6ee5fSAndroid Build Coastguard Worker %include "constraints.i" 5*58e6ee5fSAndroid Build Coastguard Worker 6*58e6ee5fSAndroid Build Coastguard Worker %nodefaultctor record; 7*58e6ee5fSAndroid Build Coastguard Worker %nodefaultdtor record; 8*58e6ee5fSAndroid Build Coastguard Worker 9*58e6ee5fSAndroid Build Coastguard Worker %apply Pointer NONNULL { struct tracecmd_input *handle }; 10*58e6ee5fSAndroid Build Coastguard Worker %apply Pointer NONNULL { struct tep_handle *pevent }; 11*58e6ee5fSAndroid Build Coastguard Worker %apply Pointer NONNULL { struct tep_format_field * }; 12*58e6ee5fSAndroid Build Coastguard Worker %apply unsigned long long *OUTPUT {unsigned long long *} 13*58e6ee5fSAndroid Build Coastguard Worker %apply int *OUTPUT {int *} 14*58e6ee5fSAndroid Build Coastguard Worker 15*58e6ee5fSAndroid Build Coastguard Worker 16*58e6ee5fSAndroid Build Coastguard Worker %{ 17*58e6ee5fSAndroid Build Coastguard Worker #include "trace-cmd.h" 18*58e6ee5fSAndroid Build Coastguard Worker #include "event-parse.h" 19*58e6ee5fSAndroid Build Coastguard Worker #include "event-utils.h" 20*58e6ee5fSAndroid Build Coastguard Worker #include <Python.h> 21*58e6ee5fSAndroid Build Coastguard Worker %} 22*58e6ee5fSAndroid Build Coastguard Worker 23*58e6ee5fSAndroid Build Coastguard Worker 24*58e6ee5fSAndroid Build Coastguard Worker %typemap(in) PyObject *pyfunc { 25*58e6ee5fSAndroid Build Coastguard Worker if (!PyCallable_Check($input)) { 26*58e6ee5fSAndroid Build Coastguard Worker PyErr_SetString(PyExc_TypeError, "Need a callable object!"); 27*58e6ee5fSAndroid Build Coastguard Worker return NULL; 28*58e6ee5fSAndroid Build Coastguard Worker } 29*58e6ee5fSAndroid Build Coastguard Worker $1 = $input; 30*58e6ee5fSAndroid Build Coastguard Worker } 31*58e6ee5fSAndroid Build Coastguard Worker 32*58e6ee5fSAndroid Build Coastguard Worker %ignore python_callback; 33*58e6ee5fSAndroid Build Coastguard Worker 34*58e6ee5fSAndroid Build Coastguard Worker %inline %{ 35*58e6ee5fSAndroid Build Coastguard Worker static int python_callback(struct trace_seq *s, 36*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record, 37*58e6ee5fSAndroid Build Coastguard Worker struct tep_event *event, 38*58e6ee5fSAndroid Build Coastguard Worker void *context); 39*58e6ee5fSAndroid Build Coastguard Worker 40*58e6ee5fSAndroid Build Coastguard Worker static int skip_output = 0; 41*58e6ee5fSAndroid Build Coastguard Worker 42*58e6ee5fSAndroid Build Coastguard Worker static void py_supress_trace_output(void) 43*58e6ee5fSAndroid Build Coastguard Worker { 44*58e6ee5fSAndroid Build Coastguard Worker skip_output = 1; 45*58e6ee5fSAndroid Build Coastguard Worker } 46*58e6ee5fSAndroid Build Coastguard Worker 47*58e6ee5fSAndroid Build Coastguard Worker void warning(const char *fmt, ...) 48*58e6ee5fSAndroid Build Coastguard Worker { 49*58e6ee5fSAndroid Build Coastguard Worker va_list ap; 50*58e6ee5fSAndroid Build Coastguard Worker 51*58e6ee5fSAndroid Build Coastguard Worker if (skip_output) 52*58e6ee5fSAndroid Build Coastguard Worker return; 53*58e6ee5fSAndroid Build Coastguard Worker 54*58e6ee5fSAndroid Build Coastguard Worker va_start(ap, fmt); 55*58e6ee5fSAndroid Build Coastguard Worker tep_vprint("tracecmd", TEP_LOG_WARNING, true, fmt, ap); 56*58e6ee5fSAndroid Build Coastguard Worker va_end(ap); 57*58e6ee5fSAndroid Build Coastguard Worker } 58*58e6ee5fSAndroid Build Coastguard Worker 59*58e6ee5fSAndroid Build Coastguard Worker PyObject *convert_pevent(unsigned long pevent) 60*58e6ee5fSAndroid Build Coastguard Worker { 61*58e6ee5fSAndroid Build Coastguard Worker void *pev = (void *)pevent; 62*58e6ee5fSAndroid Build Coastguard Worker return SWIG_NewPointerObj(SWIG_as_voidptr(pev), SWIGTYPE_p_tep_handle, 0); 63*58e6ee5fSAndroid Build Coastguard Worker } 64*58e6ee5fSAndroid Build Coastguard Worker 65*58e6ee5fSAndroid Build Coastguard Worker void py_pevent_register_event_handler(struct tep_handle *pevent, int id, 66*58e6ee5fSAndroid Build Coastguard Worker char *subsys, char *evname, 67*58e6ee5fSAndroid Build Coastguard Worker PyObject *pyfunc) 68*58e6ee5fSAndroid Build Coastguard Worker { 69*58e6ee5fSAndroid Build Coastguard Worker Py_INCREF(pyfunc); 70*58e6ee5fSAndroid Build Coastguard Worker tep_register_event_handler(pevent, id, subsys, evname, 71*58e6ee5fSAndroid Build Coastguard Worker python_callback, pyfunc); 72*58e6ee5fSAndroid Build Coastguard Worker } 73*58e6ee5fSAndroid Build Coastguard Worker 74*58e6ee5fSAndroid Build Coastguard Worker static PyObject *py_field_get_stack(struct tep_handle *pevent, 75*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record, 76*58e6ee5fSAndroid Build Coastguard Worker struct tep_event *event, 77*58e6ee5fSAndroid Build Coastguard Worker int long_size) 78*58e6ee5fSAndroid Build Coastguard Worker { 79*58e6ee5fSAndroid Build Coastguard Worker PyObject *list; 80*58e6ee5fSAndroid Build Coastguard Worker struct tep_format_field *field; 81*58e6ee5fSAndroid Build Coastguard Worker void *data = record->data; 82*58e6ee5fSAndroid Build Coastguard Worker const char *func = NULL; 83*58e6ee5fSAndroid Build Coastguard Worker unsigned long addr; 84*58e6ee5fSAndroid Build Coastguard Worker 85*58e6ee5fSAndroid Build Coastguard Worker field = tep_find_any_field(event, "caller"); 86*58e6ee5fSAndroid Build Coastguard Worker if (!field) { 87*58e6ee5fSAndroid Build Coastguard Worker PyErr_SetString(PyExc_TypeError, 88*58e6ee5fSAndroid Build Coastguard Worker "Event doesn't have caller field"); 89*58e6ee5fSAndroid Build Coastguard Worker return NULL; 90*58e6ee5fSAndroid Build Coastguard Worker } 91*58e6ee5fSAndroid Build Coastguard Worker 92*58e6ee5fSAndroid Build Coastguard Worker list = PyList_New(0); 93*58e6ee5fSAndroid Build Coastguard Worker 94*58e6ee5fSAndroid Build Coastguard Worker for (data += field->offset; data < record->data + record->size; 95*58e6ee5fSAndroid Build Coastguard Worker data += long_size) { 96*58e6ee5fSAndroid Build Coastguard Worker addr = tep_read_number(event->tep, data, long_size); 97*58e6ee5fSAndroid Build Coastguard Worker 98*58e6ee5fSAndroid Build Coastguard Worker if ((long_size == 8 && addr == (unsigned long long)-1) || 99*58e6ee5fSAndroid Build Coastguard Worker ((int)addr == -1)) 100*58e6ee5fSAndroid Build Coastguard Worker break; 101*58e6ee5fSAndroid Build Coastguard Worker func = tep_find_function(event->tep, addr); 102*58e6ee5fSAndroid Build Coastguard Worker if (PyList_Append(list, PyUnicode_FromString(func))) { 103*58e6ee5fSAndroid Build Coastguard Worker Py_DECREF(list); 104*58e6ee5fSAndroid Build Coastguard Worker return NULL; 105*58e6ee5fSAndroid Build Coastguard Worker } 106*58e6ee5fSAndroid Build Coastguard Worker } 107*58e6ee5fSAndroid Build Coastguard Worker 108*58e6ee5fSAndroid Build Coastguard Worker return list; 109*58e6ee5fSAndroid Build Coastguard Worker } 110*58e6ee5fSAndroid Build Coastguard Worker 111*58e6ee5fSAndroid Build Coastguard Worker #if PY_MAJOR_VERSION >= 3 112*58e6ee5fSAndroid Build Coastguard Worker static PyObject *fromMemory(void *buf, size_t len) 113*58e6ee5fSAndroid Build Coastguard Worker { 114*58e6ee5fSAndroid Build Coastguard Worker return PyMemoryView_FromMemory(buf, len, PyBUF_READ); 115*58e6ee5fSAndroid Build Coastguard Worker } 116*58e6ee5fSAndroid Build Coastguard Worker #define PY_INT_AS_LONG PyLong_AsLong 117*58e6ee5fSAndroid Build Coastguard Worker #else 118*58e6ee5fSAndroid Build Coastguard Worker static PyObject *fromMemory(void *buf, size_t len) 119*58e6ee5fSAndroid Build Coastguard Worker { 120*58e6ee5fSAndroid Build Coastguard Worker return PyBuffer_FromMemory(buf, len); 121*58e6ee5fSAndroid Build Coastguard Worker } 122*58e6ee5fSAndroid Build Coastguard Worker #define PY_INT_AS_LONG PyInt_AS_LONG 123*58e6ee5fSAndroid Build Coastguard Worker #endif 124*58e6ee5fSAndroid Build Coastguard Worker 125*58e6ee5fSAndroid Build Coastguard Worker 126*58e6ee5fSAndroid Build Coastguard Worker 127*58e6ee5fSAndroid Build Coastguard Worker static PyObject *py_field_get_data(struct tep_format_field *f, struct tep_record *r) 128*58e6ee5fSAndroid Build Coastguard Worker { 129*58e6ee5fSAndroid Build Coastguard Worker if (!strncmp(f->type, "__data_loc ", 11)) { 130*58e6ee5fSAndroid Build Coastguard Worker unsigned long long val; 131*58e6ee5fSAndroid Build Coastguard Worker int len, offset; 132*58e6ee5fSAndroid Build Coastguard Worker 133*58e6ee5fSAndroid Build Coastguard Worker if (tep_read_number_field(f, r->data, &val)) { 134*58e6ee5fSAndroid Build Coastguard Worker PyErr_SetString(PyExc_TypeError, 135*58e6ee5fSAndroid Build Coastguard Worker "Field is not a valid number"); 136*58e6ee5fSAndroid Build Coastguard Worker return NULL; 137*58e6ee5fSAndroid Build Coastguard Worker } 138*58e6ee5fSAndroid Build Coastguard Worker 139*58e6ee5fSAndroid Build Coastguard Worker /* 140*58e6ee5fSAndroid Build Coastguard Worker * The actual length of the dynamic array is stored 141*58e6ee5fSAndroid Build Coastguard Worker * in the top half of the field, and the offset 142*58e6ee5fSAndroid Build Coastguard Worker * is in the bottom half of the 32 bit field. 143*58e6ee5fSAndroid Build Coastguard Worker */ 144*58e6ee5fSAndroid Build Coastguard Worker offset = val & 0xffff; 145*58e6ee5fSAndroid Build Coastguard Worker len = val >> 16; 146*58e6ee5fSAndroid Build Coastguard Worker 147*58e6ee5fSAndroid Build Coastguard Worker return fromMemory(r->data + offset, len); 148*58e6ee5fSAndroid Build Coastguard Worker } 149*58e6ee5fSAndroid Build Coastguard Worker 150*58e6ee5fSAndroid Build Coastguard Worker return fromMemory(r->data + f->offset, f->size); 151*58e6ee5fSAndroid Build Coastguard Worker } 152*58e6ee5fSAndroid Build Coastguard Worker 153*58e6ee5fSAndroid Build Coastguard Worker static PyObject *py_field_get_str(struct tep_format_field *f, struct tep_record *r) 154*58e6ee5fSAndroid Build Coastguard Worker { 155*58e6ee5fSAndroid Build Coastguard Worker if (!strncmp(f->type, "__data_loc ", 11)) { 156*58e6ee5fSAndroid Build Coastguard Worker unsigned long long val; 157*58e6ee5fSAndroid Build Coastguard Worker int offset; 158*58e6ee5fSAndroid Build Coastguard Worker 159*58e6ee5fSAndroid Build Coastguard Worker if (tep_read_number_field(f, r->data, &val)) { 160*58e6ee5fSAndroid Build Coastguard Worker PyErr_SetString(PyExc_TypeError, 161*58e6ee5fSAndroid Build Coastguard Worker "Field is not a valid number"); 162*58e6ee5fSAndroid Build Coastguard Worker return NULL; 163*58e6ee5fSAndroid Build Coastguard Worker } 164*58e6ee5fSAndroid Build Coastguard Worker 165*58e6ee5fSAndroid Build Coastguard Worker /* 166*58e6ee5fSAndroid Build Coastguard Worker * The actual length of the dynamic array is stored 167*58e6ee5fSAndroid Build Coastguard Worker * in the top half of the field, and the offset 168*58e6ee5fSAndroid Build Coastguard Worker * is in the bottom half of the 32 bit field. 169*58e6ee5fSAndroid Build Coastguard Worker */ 170*58e6ee5fSAndroid Build Coastguard Worker offset = val & 0xffff; 171*58e6ee5fSAndroid Build Coastguard Worker 172*58e6ee5fSAndroid Build Coastguard Worker return PyUnicode_FromString((char *)r->data + offset); 173*58e6ee5fSAndroid Build Coastguard Worker } 174*58e6ee5fSAndroid Build Coastguard Worker 175*58e6ee5fSAndroid Build Coastguard Worker return PyUnicode_FromStringAndSize((char *)r->data + f->offset, 176*58e6ee5fSAndroid Build Coastguard Worker strnlen((char *)r->data + f->offset, f->size)); 177*58e6ee5fSAndroid Build Coastguard Worker } 178*58e6ee5fSAndroid Build Coastguard Worker 179*58e6ee5fSAndroid Build Coastguard Worker static PyObject *py_format_get_keys(struct tep_event *ef) 180*58e6ee5fSAndroid Build Coastguard Worker { 181*58e6ee5fSAndroid Build Coastguard Worker PyObject *list; 182*58e6ee5fSAndroid Build Coastguard Worker struct tep_format_field *f; 183*58e6ee5fSAndroid Build Coastguard Worker 184*58e6ee5fSAndroid Build Coastguard Worker list = PyList_New(0); 185*58e6ee5fSAndroid Build Coastguard Worker 186*58e6ee5fSAndroid Build Coastguard Worker for (f = ef->format.fields; f; f = f->next) { 187*58e6ee5fSAndroid Build Coastguard Worker if (PyList_Append(list, PyUnicode_FromString(f->name))) { 188*58e6ee5fSAndroid Build Coastguard Worker Py_DECREF(list); 189*58e6ee5fSAndroid Build Coastguard Worker return NULL; 190*58e6ee5fSAndroid Build Coastguard Worker } 191*58e6ee5fSAndroid Build Coastguard Worker } 192*58e6ee5fSAndroid Build Coastguard Worker 193*58e6ee5fSAndroid Build Coastguard Worker return list; 194*58e6ee5fSAndroid Build Coastguard Worker } 195*58e6ee5fSAndroid Build Coastguard Worker %} 196*58e6ee5fSAndroid Build Coastguard Worker 197*58e6ee5fSAndroid Build Coastguard Worker 198*58e6ee5fSAndroid Build Coastguard Worker %wrapper %{ 199*58e6ee5fSAndroid Build Coastguard Worker static int python_callback(struct trace_seq *s, 200*58e6ee5fSAndroid Build Coastguard Worker struct tep_record *record, 201*58e6ee5fSAndroid Build Coastguard Worker struct tep_event *event, 202*58e6ee5fSAndroid Build Coastguard Worker void *context) 203*58e6ee5fSAndroid Build Coastguard Worker { 204*58e6ee5fSAndroid Build Coastguard Worker PyObject *arglist, *result; 205*58e6ee5fSAndroid Build Coastguard Worker int r = 0; 206*58e6ee5fSAndroid Build Coastguard Worker 207*58e6ee5fSAndroid Build Coastguard Worker record->ref_count++; 208*58e6ee5fSAndroid Build Coastguard Worker 209*58e6ee5fSAndroid Build Coastguard Worker arglist = Py_BuildValue("(OOO)", 210*58e6ee5fSAndroid Build Coastguard Worker SWIG_NewPointerObj(SWIG_as_voidptr(s), 211*58e6ee5fSAndroid Build Coastguard Worker SWIGTYPE_p_trace_seq, 0), 212*58e6ee5fSAndroid Build Coastguard Worker SWIG_NewPointerObj(SWIG_as_voidptr(record), 213*58e6ee5fSAndroid Build Coastguard Worker SWIGTYPE_p_tep_record, 0), 214*58e6ee5fSAndroid Build Coastguard Worker SWIG_NewPointerObj(SWIG_as_voidptr(event), 215*58e6ee5fSAndroid Build Coastguard Worker SWIGTYPE_p_tep_event, 0)); 216*58e6ee5fSAndroid Build Coastguard Worker 217*58e6ee5fSAndroid Build Coastguard Worker result = PyEval_CallObject(context, arglist); 218*58e6ee5fSAndroid Build Coastguard Worker Py_XDECREF(arglist); 219*58e6ee5fSAndroid Build Coastguard Worker if (result && result != Py_None) { 220*58e6ee5fSAndroid Build Coastguard Worker if (!PyInt_Check(result)) { 221*58e6ee5fSAndroid Build Coastguard Worker PyErr_SetString(PyExc_TypeError, 222*58e6ee5fSAndroid Build Coastguard Worker "callback must return int"); 223*58e6ee5fSAndroid Build Coastguard Worker PyErr_Print(); 224*58e6ee5fSAndroid Build Coastguard Worker Py_XDECREF(result); 225*58e6ee5fSAndroid Build Coastguard Worker return 0; 226*58e6ee5fSAndroid Build Coastguard Worker } 227*58e6ee5fSAndroid Build Coastguard Worker r = PY_INT_AS_LONG(result); 228*58e6ee5fSAndroid Build Coastguard Worker } else if (result == Py_None) 229*58e6ee5fSAndroid Build Coastguard Worker r = 0; 230*58e6ee5fSAndroid Build Coastguard Worker else 231*58e6ee5fSAndroid Build Coastguard Worker PyErr_Print(); 232*58e6ee5fSAndroid Build Coastguard Worker 233*58e6ee5fSAndroid Build Coastguard Worker Py_XDECREF(result); 234*58e6ee5fSAndroid Build Coastguard Worker 235*58e6ee5fSAndroid Build Coastguard Worker return r; 236*58e6ee5fSAndroid Build Coastguard Worker } 237*58e6ee5fSAndroid Build Coastguard Worker %} 238*58e6ee5fSAndroid Build Coastguard Worker 239*58e6ee5fSAndroid Build Coastguard Worker 240*58e6ee5fSAndroid Build Coastguard Worker %ignore trace_seq_vprintf; 241*58e6ee5fSAndroid Build Coastguard Worker %ignore vpr_stat; 242*58e6ee5fSAndroid Build Coastguard Worker 243*58e6ee5fSAndroid Build Coastguard Worker /* SWIG can't grok these, define them to nothing */ 244*58e6ee5fSAndroid Build Coastguard Worker #define __trace 245*58e6ee5fSAndroid Build Coastguard Worker #define __attribute__(x) 246*58e6ee5fSAndroid Build Coastguard Worker #define __thread 247*58e6ee5fSAndroid Build Coastguard Worker 248*58e6ee5fSAndroid Build Coastguard Worker %include "trace-cmd.h" 249*58e6ee5fSAndroid Build Coastguard Worker %include <trace-seq.h> 250*58e6ee5fSAndroid Build Coastguard Worker %include <event-parse.h> 251