1
//! \file
2
/*
3
**  Copyright (C) - Triton
4
**
5
**  This program is under the terms of the Apache License 2.0.
6
*/
7

8
#include <triton/pythonObjects.hpp>
9
#include <triton/pythonUtils.hpp>
10
#include <triton/pythonXFunctions.hpp>
11
#include <triton/exceptions.hpp>
12
#include <triton/symbolicVariable.hpp>
13

14

15

16
/* setup doctest context
17

18
>>> from triton import TritonContext, REG, ARCH
19
>>> ctxt = TritonContext()
20
>>> ctxt.setArchitecture(ARCH.X86_64)
21

22
*/
23

24
/*! \page py_SymbolicVariable_page SymbolicVariable
25
    \brief [**python api**] All information about the SymbolicVariable Python object.
26

27
\tableofcontents
28

29
\section py_SymbolicVariable_description Description
30
<hr>
31

32
This object is used to represent a symbolic variable.
33

34
~~~~~~~~~~~~~{.py}
35
>>> symvar = ctxt.symbolizeRegister(ctxt.registers.rax)
36
>>> print(symvar)
37
SymVar_0:64
38

39
~~~~~~~~~~~~~
40

41
\section SymbolicVariable_py_api Python API - Methods of the SymbolicVariable class
42
<hr>
43

44
- <b>string getAlias(void)</b><br>
45
Returns the alias (if exists) of the symbolic variable.
46

47
- <b>integer getBitSize(void)</b><br>
48
Returns the size of the symbolic variable.
49

50
- <b>string getComment(void)</b><br>
51
Returns the comment (if exists) of the symbolic variable.
52

53
- <b>integer getId(void)</b><br>
54
Returns the id of the symbolic variable. This id is always unique.<br>
55
e.g: `18`
56

57
- <b>string getName(void)</b><br>
58
Returns name of the symbolic variable.<br>
59
e.g: `SymVar_18`
60

61
- <b>integer getOrigin(void)</b><br>
62
Returns the origin according to the \ref py_SYMBOLIC_page value.<br>
63
If `getType()` returns triton::engines::symbolic::REGISTER_VARIABLE, then `getOrigin()` returns the id of the register.<br>
64
Otherwise, if `getType()` returns triton::engines::symbolic::MEMORY_VARIABLE, then `getOrigin()` returns the address of the memory access.<br>
65
Then, if `getType()` returns triton::engines::symbolic::UNDEFINED_VARIABLE, then `getOrigin()` returns `0`.
66

67
- <b>\ref py_SYMBOLIC_page getType(void)</b><br>
68
Returns the type of the symbolic variable.<br>
69
e.g: `SYMBOLIC.REGISTER_VARIABLE`
70

71
- <b>void setAlias(string comment)</b><br>
72
Sets an alias to the symbolic variable.
73

74
- <b>void setComment(string comment)</b><br>
75
Sets a comment to the symbolic variable.
76

77
*/
78

79

80

81
namespace triton {
82
  namespace bindings {
83
    namespace python {
84

85
      //! SymbolicVariable destructor.
86 1
      void SymbolicVariable_dealloc(PyObject* self) {
87 1
        std::cout << std::flush;
88 1
        PySymbolicVariable_AsSymbolicVariable(self) = nullptr; // decref the shared_ptr
89 1
        Py_TYPE(self)->tp_free((PyObject*)self);
90
      }
91

92

93 1
      static PyObject* SymbolicVariable_getAlias(PyObject* self, PyObject* noarg) {
94
        try {
95 1
          return Py_BuildValue("s", PySymbolicVariable_AsSymbolicVariable(self)->getAlias().c_str());
96
        }
97 0
        catch (const triton::exceptions::Exception& e) {
98 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
99
        }
100
      }
101

102

103 1
      static PyObject* SymbolicVariable_getName(PyObject* self, PyObject* noarg) {
104
        try {
105 1
          return Py_BuildValue("s", PySymbolicVariable_AsSymbolicVariable(self)->getName().c_str());
106
        }
107 0
        catch (const triton::exceptions::Exception& e) {
108 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
109
        }
110
      }
111

112

113 1
      static PyObject* SymbolicVariable_getId(PyObject* self, PyObject* noarg) {
114
        try {
115 1
          return PyLong_FromUsize(PySymbolicVariable_AsSymbolicVariable(self)->getId());
116
        }
117 0
        catch (const triton::exceptions::Exception& e) {
118 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
119
        }
120
      }
121

122

123 1
      static PyObject* SymbolicVariable_getType(PyObject* self, PyObject* noarg) {
124
        try {
125 1
          return PyLong_FromUint32(PySymbolicVariable_AsSymbolicVariable(self)->getType());
126
        }
127 0
        catch (const triton::exceptions::Exception& e) {
128 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
129
        }
130
      }
131

132

133 1
      static PyObject* SymbolicVariable_getOrigin(PyObject* self, PyObject* noarg) {
134
        try {
135 1
          return PyLong_FromUint64(PySymbolicVariable_AsSymbolicVariable(self)->getOrigin());
136
        }
137 0
        catch (const triton::exceptions::Exception& e) {
138 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
139
        }
140
      }
141

142

143 1
      static PyObject* SymbolicVariable_getBitSize(PyObject* self, PyObject* noarg) {
144
        try {
145 1
          return PyLong_FromUint32(PySymbolicVariable_AsSymbolicVariable(self)->getSize());
146
        }
147 0
        catch (const triton::exceptions::Exception& e) {
148 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
149
        }
150
      }
151

152

153 1
      static PyObject* SymbolicVariable_getComment(PyObject* self, PyObject* noarg) {
154
        try {
155 1
          return Py_BuildValue("s", PySymbolicVariable_AsSymbolicVariable(self)->getComment().c_str());
156
        }
157 0
        catch (const triton::exceptions::Exception& e) {
158 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
159
        }
160
      }
161

162

163 1
      static PyObject* SymbolicVariable_setAlias(PyObject* self, PyObject* alias) {
164
        try {
165 1
          if (!PyStr_Check(alias))
166 0
            return PyErr_Format(PyExc_TypeError, "SymbolicVariable::setAlias(): Expected a string as argument.");
167 1
          PySymbolicVariable_AsSymbolicVariable(self)->setAlias(PyStr_AsString(alias));
168 1
          Py_INCREF(Py_None);
169 1
          return Py_None;
170
        }
171 0
        catch (const triton::exceptions::Exception& e) {
172 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
173
        }
174
      }
175

176

177 1
      static PyObject* SymbolicVariable_setComment(PyObject* self, PyObject* comment) {
178
        try {
179 1
          if (!PyStr_Check(comment))
180 0
            return PyErr_Format(PyExc_TypeError, "SymbolicVariable::setComment(): Expected a string as argument.");
181 1
          PySymbolicVariable_AsSymbolicVariable(self)->setComment(PyStr_AsString(comment));
182 1
          Py_INCREF(Py_None);
183 1
          return Py_None;
184
        }
185 0
        catch (const triton::exceptions::Exception& e) {
186 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
187
        }
188
      }
189

190

191
      #if !defined(IS_PY3_8) || !IS_PY3_8
192 0
      static int SymbolicVariable_print(PyObject* self, void* io, int s) {
193 0
        std::cout << PySymbolicVariable_AsSymbolicVariable(self);
194 0
        return 0;
195
      }
196
      #endif
197

198

199 1
      static PyObject* SymbolicVariable_str(PyObject* self) {
200
        try {
201 1
          std::stringstream str;
202 1
          str << PySymbolicVariable_AsSymbolicVariable(self);
203 1
          return PyStr_FromFormat("%s", str.str().c_str());
204
        }
205 0
        catch (const triton::exceptions::Exception& e) {
206 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
207
        }
208
      }
209

210

211 1
      static int SymbolicVariable_init(AstNode_Object* self, PyObject* args, PyObject* kwds) {
212 1
        return 0;
213
      }
214

215

216 1
      static PyObject* SymbolicVariable_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
217 1
        return type->tp_alloc(type, 0);
218
      }
219

220

221 0
      static long SymbolicVariable_hash(PyObject* self) {
222
        /* NOTE: Should be a problem if there is more than 0xffffffff variables (casting from usize to long). */
223 0
        return static_cast<long>(PySymbolicVariable_AsSymbolicVariable(self)->getId());
224
      }
225

226

227 0
      static PyObject* SymbolicVariable_richcompare(PyObject* self, PyObject* other, int op) {
228 0
        PyObject* result = nullptr;
229 0
        triton::usize id1 = 0;
230 0
        triton::usize id2 = 0;
231

232 0
        if (!PySymbolicVariable_Check(other)) {
233
          result = Py_NotImplemented;
234
        }
235
        else {
236 0
          id1 = PySymbolicVariable_AsSymbolicVariable(self)->getId();
237 0
          id2 = PySymbolicVariable_AsSymbolicVariable(other)->getId();
238

239 0
          switch (op) {
240
          case Py_LT:
241 0
            result = (id1 < id2) ? Py_True : Py_False;
242
            break;
243
          case Py_LE:
244 0
            result = (id1 <= id2) ? Py_True : Py_False;
245
            break;
246
          case Py_EQ:
247 0
            result = (id1 == id2) ? Py_True : Py_False;
248
            break;
249
          case Py_NE:
250 0
            result = (id1 != id2) ? Py_True : Py_False;
251
            break;
252
          case Py_GT:
253 0
            result = (id1 > id2) ? Py_True : Py_False;
254
            break;
255
          case Py_GE:
256 0
            result = (id1 >= id2) ? Py_True : Py_False;
257
            break;
258
          }
259
        }
260

261 0
        Py_INCREF(result);
262 0
        return result;
263
      }
264

265
      //! SymbolicVariable methods.
266
      PyMethodDef SymbolicVariable_callbacks[] = {
267
        {"getAlias",          SymbolicVariable_getAlias,          METH_NOARGS,    ""},
268
        {"getBitSize",        SymbolicVariable_getBitSize,        METH_NOARGS,    ""},
269
        {"getComment",        SymbolicVariable_getComment,        METH_NOARGS,    ""},
270
        {"getId",             SymbolicVariable_getId,             METH_NOARGS,    ""},
271
        {"getName",           SymbolicVariable_getName,           METH_NOARGS,    ""},
272
        {"getOrigin",         SymbolicVariable_getOrigin,         METH_NOARGS,    ""},
273
        {"getType",           SymbolicVariable_getType,           METH_NOARGS,    ""},
274
        {"setAlias",          SymbolicVariable_setAlias,          METH_O,         ""},
275
        {"setComment",        SymbolicVariable_setComment,        METH_O,         ""},
276
        {nullptr,             nullptr,                            0,              nullptr}
277
      };
278

279

280
      PyTypeObject SymbolicVariable_Type = {
281
        PyVarObject_HEAD_INIT(&PyType_Type, 0)
282
        "SymbolicVariable",                         /* tp_name */
283
        sizeof(SymbolicVariable_Object),            /* tp_basicsize */
284
        0,                                          /* tp_itemsize */
285
        (destructor)SymbolicVariable_dealloc,       /* tp_dealloc */
286
        #if IS_PY3_8
287
        0,                                          /* tp_vectorcall_offset */
288
        #else
289
        (printfunc)SymbolicVariable_print,          /* tp_print */
290
        #endif
291
        0,                                          /* tp_getattr */
292
        0,                                          /* tp_setattr */
293
        0,                                          /* tp_compare */
294
        (reprfunc)SymbolicVariable_str,             /* tp_repr */
295
        0,                                          /* tp_as_number */
296
        0,                                          /* tp_as_sequence */
297
        0,                                          /* tp_as_mapping */
298
        (hashfunc)SymbolicVariable_hash,            /* tp_hash */
299
        0,                                          /* tp_call */
300
        (reprfunc)SymbolicVariable_str,             /* tp_str */
301
        0,                                          /* tp_getattro */
302
        0,                                          /* tp_setattro */
303
        0,                                          /* tp_as_buffer */
304
        Py_TPFLAGS_DEFAULT,                         /* tp_flags */
305
        "SymbolicVariable objects",                 /* tp_doc */
306
        0,                                          /* tp_traverse */
307
        0,                                          /* tp_clear */
308
        SymbolicVariable_richcompare,               /* tp_richcompare */
309
        0,                                          /* tp_weaklistoffset */
310
        0,                                          /* tp_iter */
311
        0,                                          /* tp_iternext */
312
        SymbolicVariable_callbacks,                 /* tp_methods */
313
        0,                                          /* tp_members */
314
        0,                                          /* tp_getset */
315
        0,                                          /* tp_base */
316
        0,                                          /* tp_dict */
317
        0,                                          /* tp_descr_get */
318
        0,                                          /* tp_descr_set */
319
        0,                                          /* tp_dictoffset */
320
        (initproc)SymbolicVariable_init,            /* tp_init */
321
        0,                                          /* tp_alloc */
322
        (newfunc)SymbolicVariable_new,              /* tp_new */
323
        0,                                          /* tp_free */
324
        0,                                          /* tp_is_gc */
325
        0,                                          /* tp_bases */
326
        0,                                          /* tp_mro */
327
        0,                                          /* tp_cache */
328
        0,                                          /* tp_subclasses */
329
        0,                                          /* tp_weaklist */
330
        0,                                          /* tp_del */
331
        #if IS_PY3
332
          0,                                        /* tp_version_tag */
333
          0,                                        /* tp_finalize */
334
          #if IS_PY3_8
335
            0,                                      /* tp_vectorcall */
336
            #if !IS_PY3_9
337
              0,                                    /* bpo-37250: kept for backwards compatibility in CPython 3.8 only */
338
            #endif
339
          #endif
340
        #else
341
          0                                         /* tp_version_tag */
342
        #endif
343
      };
344

345

346 1
      PyObject* PySymbolicVariable(const triton::engines::symbolic::SharedSymbolicVariable& symVar) {
347 1
        if (symVar == nullptr) {
348 0
          Py_INCREF(Py_None);
349 0
          return Py_None;
350
        }
351

352 1
        PyType_Ready(&SymbolicVariable_Type);
353
        // Build the new object the python way (calling operator() on the type) as
354
        // it crash otherwise (certainly due to incorrect shared_ptr initialization).
355 1
        auto* object = (triton::bindings::python::SymbolicVariable_Object*)PyObject_CallObject((PyObject*)&SymbolicVariable_Type, nullptr);
356 1
        if (object != NULL) {
357 1
          object->symVar = symVar;
358
        }
359

360
        return (PyObject*)object;
361
      }
362

363
    }; /* python namespace */
364
  }; /* bindings namespace */
365 1
}; /* triton namespace */

Read our documentation on viewing source code .

Loading