11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
27e4b21b8STom Zanussi /*
3133dc4c3SIngo Molnar  * Context.c.  Python interfaces for perf script.
47e4b21b8STom Zanussi  *
57e4b21b8STom Zanussi  * Copyright (C) 2010 Tom Zanussi <[email protected]>
67e4b21b8STom Zanussi  */
77e4b21b8STom Zanussi 
87e4b21b8STom Zanussi #include <Python.h>
97e4b21b8STom Zanussi #include "../../../util/trace-event.h"
1013c71b92SAdrian Hunter #include "../../../util/event.h"
1113c71b92SAdrian Hunter #include "../../../util/symbol.h"
1213c71b92SAdrian Hunter #include "../../../util/thread.h"
1313c71b92SAdrian Hunter #include "../../../util/maps.h"
14*7d00540dSAdrian Hunter #include "../../../util/auxtrace.h"
15*7d00540dSAdrian Hunter #include "../../../util/session.h"
167e4b21b8STom Zanussi 
1766dfdff0SJaroslav Škarvada #if PY_MAJOR_VERSION < 3
1866dfdff0SJaroslav Škarvada #define _PyCapsule_GetPointer(arg1, arg2) \
1966dfdff0SJaroslav Škarvada   PyCObject_AsVoidPtr(arg1)
2013c71b92SAdrian Hunter #define _PyBytes_FromStringAndSize(arg1, arg2) \
2113c71b92SAdrian Hunter   PyString_FromStringAndSize((arg1), (arg2))
22*7d00540dSAdrian Hunter #define _PyUnicode_AsUTF8(arg) \
23*7d00540dSAdrian Hunter   PyString_AsString(arg)
2466dfdff0SJaroslav Škarvada 
257e4b21b8STom Zanussi PyMODINIT_FUNC initperf_trace_context(void);
2666dfdff0SJaroslav Škarvada #else
2766dfdff0SJaroslav Škarvada #define _PyCapsule_GetPointer(arg1, arg2) \
2866dfdff0SJaroslav Škarvada   PyCapsule_GetPointer((arg1), (arg2))
2913c71b92SAdrian Hunter #define _PyBytes_FromStringAndSize(arg1, arg2) \
3013c71b92SAdrian Hunter   PyBytes_FromStringAndSize((arg1), (arg2))
31*7d00540dSAdrian Hunter #define _PyUnicode_AsUTF8(arg) \
32*7d00540dSAdrian Hunter   PyUnicode_AsUTF8(arg)
3366dfdff0SJaroslav Škarvada 
3466dfdff0SJaroslav Škarvada PyMODINIT_FUNC PyInit_perf_trace_context(void);
3566dfdff0SJaroslav Škarvada #endif
367e4b21b8STom Zanussi 
37*7d00540dSAdrian Hunter static struct scripting_context *get_args(PyObject *args, const char *name, PyObject **arg2)
387e4b21b8STom Zanussi {
39*7d00540dSAdrian Hunter 	int cnt = 1 + !!arg2;
407e4b21b8STom Zanussi 	PyObject *context;
417e4b21b8STom Zanussi 
42*7d00540dSAdrian Hunter 	if (!PyArg_UnpackTuple(args, name, 1, cnt, &context, arg2))
437e4b21b8STom Zanussi 		return NULL;
447e4b21b8STom Zanussi 
456337bd0cSAdrian Hunter 	return _PyCapsule_GetPointer(context, NULL);
466337bd0cSAdrian Hunter }
477e4b21b8STom Zanussi 
48*7d00540dSAdrian Hunter static struct scripting_context *get_scripting_context(PyObject *args)
49*7d00540dSAdrian Hunter {
50*7d00540dSAdrian Hunter 	return get_args(args, "context", NULL);
51*7d00540dSAdrian Hunter }
52*7d00540dSAdrian Hunter 
536337bd0cSAdrian Hunter static PyObject *perf_trace_context_common_pc(PyObject *obj, PyObject *args)
546337bd0cSAdrian Hunter {
556337bd0cSAdrian Hunter 	struct scripting_context *c = get_scripting_context(args);
566337bd0cSAdrian Hunter 
576337bd0cSAdrian Hunter 	if (!c)
586337bd0cSAdrian Hunter 		return NULL;
596337bd0cSAdrian Hunter 
606337bd0cSAdrian Hunter 	return Py_BuildValue("i", common_pc(c));
617e4b21b8STom Zanussi }
627e4b21b8STom Zanussi 
63316c7136SArnaldo Carvalho de Melo static PyObject *perf_trace_context_common_flags(PyObject *obj,
647e4b21b8STom Zanussi 						 PyObject *args)
657e4b21b8STom Zanussi {
666337bd0cSAdrian Hunter 	struct scripting_context *c = get_scripting_context(args);
677e4b21b8STom Zanussi 
686337bd0cSAdrian Hunter 	if (!c)
697e4b21b8STom Zanussi 		return NULL;
707e4b21b8STom Zanussi 
716337bd0cSAdrian Hunter 	return Py_BuildValue("i", common_flags(c));
727e4b21b8STom Zanussi }
737e4b21b8STom Zanussi 
74316c7136SArnaldo Carvalho de Melo static PyObject *perf_trace_context_common_lock_depth(PyObject *obj,
757e4b21b8STom Zanussi 						      PyObject *args)
767e4b21b8STom Zanussi {
776337bd0cSAdrian Hunter 	struct scripting_context *c = get_scripting_context(args);
787e4b21b8STom Zanussi 
796337bd0cSAdrian Hunter 	if (!c)
807e4b21b8STom Zanussi 		return NULL;
817e4b21b8STom Zanussi 
826337bd0cSAdrian Hunter 	return Py_BuildValue("i", common_lock_depth(c));
837e4b21b8STom Zanussi }
847e4b21b8STom Zanussi 
8513c71b92SAdrian Hunter static PyObject *perf_sample_insn(PyObject *obj, PyObject *args)
8613c71b92SAdrian Hunter {
8713c71b92SAdrian Hunter 	struct scripting_context *c = get_scripting_context(args);
8813c71b92SAdrian Hunter 
8913c71b92SAdrian Hunter 	if (!c)
9013c71b92SAdrian Hunter 		return NULL;
9113c71b92SAdrian Hunter 
9213c71b92SAdrian Hunter 	if (c->sample->ip && !c->sample->insn_len &&
9313c71b92SAdrian Hunter 	    c->al->thread->maps && c->al->thread->maps->machine)
9413c71b92SAdrian Hunter 		script_fetch_insn(c->sample, c->al->thread, c->al->thread->maps->machine);
9513c71b92SAdrian Hunter 
9613c71b92SAdrian Hunter 	if (!c->sample->insn_len)
9713c71b92SAdrian Hunter 		Py_RETURN_NONE; /* N.B. This is a return statement */
9813c71b92SAdrian Hunter 
9913c71b92SAdrian Hunter 	return _PyBytes_FromStringAndSize(c->sample->insn, c->sample->insn_len);
10013c71b92SAdrian Hunter }
10113c71b92SAdrian Hunter 
102*7d00540dSAdrian Hunter static PyObject *perf_set_itrace_options(PyObject *obj, PyObject *args)
103*7d00540dSAdrian Hunter {
104*7d00540dSAdrian Hunter 	struct scripting_context *c;
105*7d00540dSAdrian Hunter 	const char *itrace_options;
106*7d00540dSAdrian Hunter 	int retval = -1;
107*7d00540dSAdrian Hunter 	PyObject *str;
108*7d00540dSAdrian Hunter 
109*7d00540dSAdrian Hunter 	c = get_args(args, "itrace_options", &str);
110*7d00540dSAdrian Hunter 	if (!c)
111*7d00540dSAdrian Hunter 		return NULL;
112*7d00540dSAdrian Hunter 
113*7d00540dSAdrian Hunter 	if (!c->session || !c->session->itrace_synth_opts)
114*7d00540dSAdrian Hunter 		goto out;
115*7d00540dSAdrian Hunter 
116*7d00540dSAdrian Hunter 	if (c->session->itrace_synth_opts->set) {
117*7d00540dSAdrian Hunter 		retval = 1;
118*7d00540dSAdrian Hunter 		goto out;
119*7d00540dSAdrian Hunter 	}
120*7d00540dSAdrian Hunter 
121*7d00540dSAdrian Hunter 	itrace_options = _PyUnicode_AsUTF8(str);
122*7d00540dSAdrian Hunter 
123*7d00540dSAdrian Hunter 	retval = itrace_do_parse_synth_opts(c->session->itrace_synth_opts, itrace_options, 0);
124*7d00540dSAdrian Hunter out:
125*7d00540dSAdrian Hunter 	return Py_BuildValue("i", retval);
126*7d00540dSAdrian Hunter }
127*7d00540dSAdrian Hunter 
1287e4b21b8STom Zanussi static PyMethodDef ContextMethods[] = {
1297e4b21b8STom Zanussi 	{ "common_pc", perf_trace_context_common_pc, METH_VARARGS,
1307e4b21b8STom Zanussi 	  "Get the common preempt count event field value."},
1317e4b21b8STom Zanussi 	{ "common_flags", perf_trace_context_common_flags, METH_VARARGS,
1327e4b21b8STom Zanussi 	  "Get the common flags event field value."},
1337e4b21b8STom Zanussi 	{ "common_lock_depth", perf_trace_context_common_lock_depth,
1347e4b21b8STom Zanussi 	  METH_VARARGS,	"Get the common lock depth event field value."},
13513c71b92SAdrian Hunter 	{ "perf_sample_insn", perf_sample_insn,
13613c71b92SAdrian Hunter 	  METH_VARARGS,	"Get the machine code instruction."},
137*7d00540dSAdrian Hunter 	{ "perf_set_itrace_options", perf_set_itrace_options,
138*7d00540dSAdrian Hunter 	  METH_VARARGS,	"Set --itrace options."},
1397e4b21b8STom Zanussi 	{ NULL, NULL, 0, NULL}
1407e4b21b8STom Zanussi };
1417e4b21b8STom Zanussi 
14266dfdff0SJaroslav Škarvada #if PY_MAJOR_VERSION < 3
1437e4b21b8STom Zanussi PyMODINIT_FUNC initperf_trace_context(void)
1447e4b21b8STom Zanussi {
1457e4b21b8STom Zanussi 	(void) Py_InitModule("perf_trace_context", ContextMethods);
1467e4b21b8STom Zanussi }
14766dfdff0SJaroslav Škarvada #else
14866dfdff0SJaroslav Škarvada PyMODINIT_FUNC PyInit_perf_trace_context(void)
14966dfdff0SJaroslav Škarvada {
15066dfdff0SJaroslav Škarvada 	static struct PyModuleDef moduledef = {
15166dfdff0SJaroslav Škarvada 		PyModuleDef_HEAD_INIT,
15266dfdff0SJaroslav Škarvada 		"perf_trace_context",	/* m_name */
15366dfdff0SJaroslav Škarvada 		"",			/* m_doc */
15466dfdff0SJaroslav Škarvada 		-1,			/* m_size */
15566dfdff0SJaroslav Škarvada 		ContextMethods,		/* m_methods */
15666dfdff0SJaroslav Škarvada 		NULL,			/* m_reload */
15766dfdff0SJaroslav Škarvada 		NULL,			/* m_traverse */
15866dfdff0SJaroslav Škarvada 		NULL,			/* m_clear */
15966dfdff0SJaroslav Škarvada 		NULL,			/* m_free */
16066dfdff0SJaroslav Škarvada 	};
161cf9bfa6cSAdrian Hunter 	PyObject *mod;
162cf9bfa6cSAdrian Hunter 
163cf9bfa6cSAdrian Hunter 	mod = PyModule_Create(&moduledef);
164cf9bfa6cSAdrian Hunter 	/* Add perf_script_context to the module so it can be imported */
165cf9bfa6cSAdrian Hunter 	PyObject_SetAttrString(mod, "perf_script_context", Py_None);
166cf9bfa6cSAdrian Hunter 
167cf9bfa6cSAdrian Hunter 	return mod;
16866dfdff0SJaroslav Škarvada }
16966dfdff0SJaroslav Škarvada #endif
170