cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

Context.c (5816B)


      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 <tzanussi@gmail.com>
      6 */
      7
      8/*
      9 * Use Py_ssize_t for '#' formats to avoid DeprecationWarning: PY_SSIZE_T_CLEAN
     10 * will be required for '#' formats.
     11 */
     12#define PY_SSIZE_T_CLEAN
     13
     14#include <Python.h>
     15#include "../../../util/trace-event.h"
     16#include "../../../util/event.h"
     17#include "../../../util/symbol.h"
     18#include "../../../util/thread.h"
     19#include "../../../util/map.h"
     20#include "../../../util/maps.h"
     21#include "../../../util/auxtrace.h"
     22#include "../../../util/session.h"
     23#include "../../../util/srcline.h"
     24#include "../../../util/srccode.h"
     25
     26#if PY_MAJOR_VERSION < 3
     27#define _PyCapsule_GetPointer(arg1, arg2) \
     28  PyCObject_AsVoidPtr(arg1)
     29#define _PyBytes_FromStringAndSize(arg1, arg2) \
     30  PyString_FromStringAndSize((arg1), (arg2))
     31#define _PyUnicode_AsUTF8(arg) \
     32  PyString_AsString(arg)
     33
     34PyMODINIT_FUNC initperf_trace_context(void);
     35#else
     36#define _PyCapsule_GetPointer(arg1, arg2) \
     37  PyCapsule_GetPointer((arg1), (arg2))
     38#define _PyBytes_FromStringAndSize(arg1, arg2) \
     39  PyBytes_FromStringAndSize((arg1), (arg2))
     40#define _PyUnicode_AsUTF8(arg) \
     41  PyUnicode_AsUTF8(arg)
     42
     43PyMODINIT_FUNC PyInit_perf_trace_context(void);
     44#endif
     45
     46static struct scripting_context *get_args(PyObject *args, const char *name, PyObject **arg2)
     47{
     48	int cnt = 1 + !!arg2;
     49	PyObject *context;
     50
     51	if (!PyArg_UnpackTuple(args, name, 1, cnt, &context, arg2))
     52		return NULL;
     53
     54	return _PyCapsule_GetPointer(context, NULL);
     55}
     56
     57static struct scripting_context *get_scripting_context(PyObject *args)
     58{
     59	return get_args(args, "context", NULL);
     60}
     61
     62static PyObject *perf_trace_context_common_pc(PyObject *obj, PyObject *args)
     63{
     64	struct scripting_context *c = get_scripting_context(args);
     65
     66	if (!c)
     67		return NULL;
     68
     69	return Py_BuildValue("i", common_pc(c));
     70}
     71
     72static PyObject *perf_trace_context_common_flags(PyObject *obj,
     73						 PyObject *args)
     74{
     75	struct scripting_context *c = get_scripting_context(args);
     76
     77	if (!c)
     78		return NULL;
     79
     80	return Py_BuildValue("i", common_flags(c));
     81}
     82
     83static PyObject *perf_trace_context_common_lock_depth(PyObject *obj,
     84						      PyObject *args)
     85{
     86	struct scripting_context *c = get_scripting_context(args);
     87
     88	if (!c)
     89		return NULL;
     90
     91	return Py_BuildValue("i", common_lock_depth(c));
     92}
     93
     94static PyObject *perf_sample_insn(PyObject *obj, PyObject *args)
     95{
     96	struct scripting_context *c = get_scripting_context(args);
     97
     98	if (!c)
     99		return NULL;
    100
    101	if (c->sample->ip && !c->sample->insn_len &&
    102	    c->al->thread->maps && c->al->thread->maps->machine)
    103		script_fetch_insn(c->sample, c->al->thread, c->al->thread->maps->machine);
    104
    105	if (!c->sample->insn_len)
    106		Py_RETURN_NONE; /* N.B. This is a return statement */
    107
    108	return _PyBytes_FromStringAndSize(c->sample->insn, c->sample->insn_len);
    109}
    110
    111static PyObject *perf_set_itrace_options(PyObject *obj, PyObject *args)
    112{
    113	struct scripting_context *c;
    114	const char *itrace_options;
    115	int retval = -1;
    116	PyObject *str;
    117
    118	c = get_args(args, "itrace_options", &str);
    119	if (!c)
    120		return NULL;
    121
    122	if (!c->session || !c->session->itrace_synth_opts)
    123		goto out;
    124
    125	if (c->session->itrace_synth_opts->set) {
    126		retval = 1;
    127		goto out;
    128	}
    129
    130	itrace_options = _PyUnicode_AsUTF8(str);
    131
    132	retval = itrace_do_parse_synth_opts(c->session->itrace_synth_opts, itrace_options, 0);
    133out:
    134	return Py_BuildValue("i", retval);
    135}
    136
    137static PyObject *perf_sample_src(PyObject *obj, PyObject *args, bool get_srccode)
    138{
    139	struct scripting_context *c = get_scripting_context(args);
    140	unsigned int line = 0;
    141	char *srcfile = NULL;
    142	char *srccode = NULL;
    143	PyObject *result;
    144	struct map *map;
    145	int len = 0;
    146	u64 addr;
    147
    148	if (!c)
    149		return NULL;
    150
    151	map = c->al->map;
    152	addr = c->al->addr;
    153
    154	if (map && map->dso)
    155		srcfile = get_srcline_split(map->dso, map__rip_2objdump(map, addr), &line);
    156
    157	if (get_srccode) {
    158		if (srcfile)
    159			srccode = find_sourceline(srcfile, line, &len);
    160		result = Py_BuildValue("(sIs#)", srcfile, line, srccode, (Py_ssize_t)len);
    161	} else {
    162		result = Py_BuildValue("(sI)", srcfile, line);
    163	}
    164
    165	free(srcfile);
    166
    167	return result;
    168}
    169
    170static PyObject *perf_sample_srcline(PyObject *obj, PyObject *args)
    171{
    172	return perf_sample_src(obj, args, false);
    173}
    174
    175static PyObject *perf_sample_srccode(PyObject *obj, PyObject *args)
    176{
    177	return perf_sample_src(obj, args, true);
    178}
    179
    180static PyMethodDef ContextMethods[] = {
    181	{ "common_pc", perf_trace_context_common_pc, METH_VARARGS,
    182	  "Get the common preempt count event field value."},
    183	{ "common_flags", perf_trace_context_common_flags, METH_VARARGS,
    184	  "Get the common flags event field value."},
    185	{ "common_lock_depth", perf_trace_context_common_lock_depth,
    186	  METH_VARARGS,	"Get the common lock depth event field value."},
    187	{ "perf_sample_insn", perf_sample_insn,
    188	  METH_VARARGS,	"Get the machine code instruction."},
    189	{ "perf_set_itrace_options", perf_set_itrace_options,
    190	  METH_VARARGS,	"Set --itrace options."},
    191	{ "perf_sample_srcline", perf_sample_srcline,
    192	  METH_VARARGS,	"Get source file name and line number."},
    193	{ "perf_sample_srccode", perf_sample_srccode,
    194	  METH_VARARGS,	"Get source file name, line number and line."},
    195	{ NULL, NULL, 0, NULL}
    196};
    197
    198#if PY_MAJOR_VERSION < 3
    199PyMODINIT_FUNC initperf_trace_context(void)
    200{
    201	(void) Py_InitModule("perf_trace_context", ContextMethods);
    202}
    203#else
    204PyMODINIT_FUNC PyInit_perf_trace_context(void)
    205{
    206	static struct PyModuleDef moduledef = {
    207		PyModuleDef_HEAD_INIT,
    208		"perf_trace_context",	/* m_name */
    209		"",			/* m_doc */
    210		-1,			/* m_size */
    211		ContextMethods,		/* m_methods */
    212		NULL,			/* m_reload */
    213		NULL,			/* m_traverse */
    214		NULL,			/* m_clear */
    215		NULL,			/* m_free */
    216	};
    217	PyObject *mod;
    218
    219	mod = PyModule_Create(&moduledef);
    220	/* Add perf_script_context to the module so it can be imported */
    221	PyObject_SetAttrString(mod, "perf_script_context", Py_None);
    222
    223	return mod;
    224}
    225#endif