1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Context.c. Python interfaces for perf script. 4 * 5 * Copyright (C) 2010 Tom Zanussi <[email protected]> 6 */ 7 8 #include <Python.h> 9 #include "../../../util/trace-event.h" 10 #include "../../../util/event.h" 11 #include "../../../util/symbol.h" 12 #include "../../../util/thread.h" 13 #include "../../../util/maps.h" 14 #include "../../../util/auxtrace.h" 15 #include "../../../util/session.h" 16 17 #if PY_MAJOR_VERSION < 3 18 #define _PyCapsule_GetPointer(arg1, arg2) \ 19 PyCObject_AsVoidPtr(arg1) 20 #define _PyBytes_FromStringAndSize(arg1, arg2) \ 21 PyString_FromStringAndSize((arg1), (arg2)) 22 #define _PyUnicode_AsUTF8(arg) \ 23 PyString_AsString(arg) 24 25 PyMODINIT_FUNC initperf_trace_context(void); 26 #else 27 #define _PyCapsule_GetPointer(arg1, arg2) \ 28 PyCapsule_GetPointer((arg1), (arg2)) 29 #define _PyBytes_FromStringAndSize(arg1, arg2) \ 30 PyBytes_FromStringAndSize((arg1), (arg2)) 31 #define _PyUnicode_AsUTF8(arg) \ 32 PyUnicode_AsUTF8(arg) 33 34 PyMODINIT_FUNC PyInit_perf_trace_context(void); 35 #endif 36 37 static struct scripting_context *get_args(PyObject *args, const char *name, PyObject **arg2) 38 { 39 int cnt = 1 + !!arg2; 40 PyObject *context; 41 42 if (!PyArg_UnpackTuple(args, name, 1, cnt, &context, arg2)) 43 return NULL; 44 45 return _PyCapsule_GetPointer(context, NULL); 46 } 47 48 static struct scripting_context *get_scripting_context(PyObject *args) 49 { 50 return get_args(args, "context", NULL); 51 } 52 53 static PyObject *perf_trace_context_common_pc(PyObject *obj, PyObject *args) 54 { 55 struct scripting_context *c = get_scripting_context(args); 56 57 if (!c) 58 return NULL; 59 60 return Py_BuildValue("i", common_pc(c)); 61 } 62 63 static PyObject *perf_trace_context_common_flags(PyObject *obj, 64 PyObject *args) 65 { 66 struct scripting_context *c = get_scripting_context(args); 67 68 if (!c) 69 return NULL; 70 71 return Py_BuildValue("i", common_flags(c)); 72 } 73 74 static PyObject *perf_trace_context_common_lock_depth(PyObject *obj, 75 PyObject *args) 76 { 77 struct scripting_context *c = get_scripting_context(args); 78 79 if (!c) 80 return NULL; 81 82 return Py_BuildValue("i", common_lock_depth(c)); 83 } 84 85 static PyObject *perf_sample_insn(PyObject *obj, PyObject *args) 86 { 87 struct scripting_context *c = get_scripting_context(args); 88 89 if (!c) 90 return NULL; 91 92 if (c->sample->ip && !c->sample->insn_len && 93 c->al->thread->maps && c->al->thread->maps->machine) 94 script_fetch_insn(c->sample, c->al->thread, c->al->thread->maps->machine); 95 96 if (!c->sample->insn_len) 97 Py_RETURN_NONE; /* N.B. This is a return statement */ 98 99 return _PyBytes_FromStringAndSize(c->sample->insn, c->sample->insn_len); 100 } 101 102 static PyObject *perf_set_itrace_options(PyObject *obj, PyObject *args) 103 { 104 struct scripting_context *c; 105 const char *itrace_options; 106 int retval = -1; 107 PyObject *str; 108 109 c = get_args(args, "itrace_options", &str); 110 if (!c) 111 return NULL; 112 113 if (!c->session || !c->session->itrace_synth_opts) 114 goto out; 115 116 if (c->session->itrace_synth_opts->set) { 117 retval = 1; 118 goto out; 119 } 120 121 itrace_options = _PyUnicode_AsUTF8(str); 122 123 retval = itrace_do_parse_synth_opts(c->session->itrace_synth_opts, itrace_options, 0); 124 out: 125 return Py_BuildValue("i", retval); 126 } 127 128 static PyMethodDef ContextMethods[] = { 129 { "common_pc", perf_trace_context_common_pc, METH_VARARGS, 130 "Get the common preempt count event field value."}, 131 { "common_flags", perf_trace_context_common_flags, METH_VARARGS, 132 "Get the common flags event field value."}, 133 { "common_lock_depth", perf_trace_context_common_lock_depth, 134 METH_VARARGS, "Get the common lock depth event field value."}, 135 { "perf_sample_insn", perf_sample_insn, 136 METH_VARARGS, "Get the machine code instruction."}, 137 { "perf_set_itrace_options", perf_set_itrace_options, 138 METH_VARARGS, "Set --itrace options."}, 139 { NULL, NULL, 0, NULL} 140 }; 141 142 #if PY_MAJOR_VERSION < 3 143 PyMODINIT_FUNC initperf_trace_context(void) 144 { 145 (void) Py_InitModule("perf_trace_context", ContextMethods); 146 } 147 #else 148 PyMODINIT_FUNC PyInit_perf_trace_context(void) 149 { 150 static struct PyModuleDef moduledef = { 151 PyModuleDef_HEAD_INIT, 152 "perf_trace_context", /* m_name */ 153 "", /* m_doc */ 154 -1, /* m_size */ 155 ContextMethods, /* m_methods */ 156 NULL, /* m_reload */ 157 NULL, /* m_traverse */ 158 NULL, /* m_clear */ 159 NULL, /* m_free */ 160 }; 161 PyObject *mod; 162 163 mod = PyModule_Create(&moduledef); 164 /* Add perf_script_context to the module so it can be imported */ 165 PyObject_SetAttrString(mod, "perf_script_context", Py_None); 166 167 return mod; 168 } 169 #endif 170