diff options
Diffstat (limited to 'tools/perf/util/python.c')
-rw-r--r-- | tools/perf/util/python.c | 92 |
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 | ||
293 | static bool is_tracepoint(struct pyrf_event *pevent) | ||
294 | { | ||
295 | return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT; | ||
296 | } | ||
297 | |||
298 | static 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 | |||
310 | static PyObject* | ||
311 | tracepoint_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 | |||
349 | static PyObject* | ||
350 | get_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 | |||
373 | static PyObject* | ||
374 | pyrf_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 | |||
293 | static PyTypeObject pyrf_sample_event__type = { | 384 | static 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 | ||
303 | static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object."); | 395 | static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object."); |