aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/python.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/python.c')
-rw-r--r--tools/perf/util/python.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index dc7adaa3a02c..d32f97033718 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -290,6 +290,97 @@ static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent)
290 return ret; 290 return ret;
291} 291}
292 292
293static bool is_tracepoint(struct pyrf_event *pevent)
294{
295 return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT;
296}
297
298static int is_printable_array(char *p, unsigned int len)
299{
300 unsigned int i;
301
302 for (i = 0; i < len; i++) {
303 if (!isprint(p[i]) && !isspace(p[i]))
304 return 0;
305 }
306
307 return 1;
308}
309
310static PyObject*
311tracepoint_field(struct pyrf_event *pe, struct format_field *field)
312{
313 struct pevent *pevent = field->event->pevent;
314 void *data = pe->sample.raw_data;
315 PyObject *ret = NULL;
316 unsigned long long val;
317 unsigned int offset, len;
318
319 if (field->flags & FIELD_IS_ARRAY) {
320 offset = field->offset;
321 len = field->size;
322 if (field->flags & FIELD_IS_DYNAMIC) {
323 val = pevent_read_number(pevent, data + offset, len);
324 offset = val;
325 len = offset >> 16;
326 offset &= 0xffff;
327 }
328 if (field->flags & FIELD_IS_STRING &&
329 is_printable_array(data + offset, len)) {
330 ret = PyString_FromString((char *)data + offset);
331 } else {
332 ret = PyByteArray_FromStringAndSize((const char *) data + offset, len);
333 field->flags &= ~FIELD_IS_STRING;
334 }
335 } else {
336 val = pevent_read_number(pevent, data + field->offset,
337 field->size);
338 if (field->flags & FIELD_IS_POINTER)
339 ret = PyLong_FromUnsignedLong((unsigned long) val);
340 else if (field->flags & FIELD_IS_SIGNED)
341 ret = PyLong_FromLong((long) val);
342 else
343 ret = PyLong_FromUnsignedLong((unsigned long) val);
344 }
345
346 return ret;
347}
348
349static PyObject*
350get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
351{
352 const char *str = PyString_AsString(PyObject_Str(attr_name));
353 struct perf_evsel *evsel = pevent->evsel;
354 struct format_field *field;
355
356 if (!evsel->tp_format) {
357 struct event_format *tp_format;
358
359 tp_format = trace_event__tp_format_id(evsel->attr.config);
360 if (!tp_format)
361 return NULL;
362
363 evsel->tp_format = tp_format;
364 }
365
366 field = pevent_find_any_field(evsel->tp_format, str);
367 if (!field)
368 return NULL;
369
370 return tracepoint_field(pevent, field);
371}
372
373static PyObject*
374pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name)
375{
376 PyObject *obj = NULL;
377
378 if (is_tracepoint(pevent))
379 obj = get_tracepoint_field(pevent, attr_name);
380
381 return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name);
382}
383
293static PyTypeObject pyrf_sample_event__type = { 384static PyTypeObject pyrf_sample_event__type = {
294 PyVarObject_HEAD_INIT(NULL, 0) 385 PyVarObject_HEAD_INIT(NULL, 0)
295 .tp_name = "perf.sample_event", 386 .tp_name = "perf.sample_event",
@@ -298,6 +389,7 @@ static PyTypeObject pyrf_sample_event__type = {
298 .tp_doc = pyrf_sample_event__doc, 389 .tp_doc = pyrf_sample_event__doc,
299 .tp_members = pyrf_sample_event__members, 390 .tp_members = pyrf_sample_event__members,
300 .tp_repr = (reprfunc)pyrf_sample_event__repr, 391 .tp_repr = (reprfunc)pyrf_sample_event__repr,
392 .tp_getattro = (getattrofunc) pyrf_sample_event__getattro,
301}; 393};
302 394
303static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object."); 395static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");