Home | History | Annotate | Line # | Download | only in python
      1      1.1  christos /* Python interface to record targets.
      2      1.1  christos 
      3  1.1.1.5  christos    Copyright 2016-2024 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    This file is part of GDB.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20      1.1  christos #include "py-instruction.h"
     21      1.1  christos #include "py-record.h"
     22      1.1  christos #include "py-record-btrace.h"
     23      1.1  christos #include "py-record-full.h"
     24      1.1  christos #include "target.h"
     25  1.1.1.2  christos #include "gdbthread.h"
     26      1.1  christos 
     27      1.1  christos /* Python Record type.  */
     28      1.1  christos 
     29      1.1  christos static PyTypeObject recpy_record_type = {
     30      1.1  christos   PyVarObject_HEAD_INIT (NULL, 0)
     31      1.1  christos };
     32      1.1  christos 
     33      1.1  christos /* Python RecordInstruction type.  */
     34      1.1  christos 
     35      1.1  christos PyTypeObject recpy_insn_type = {
     36      1.1  christos   PyVarObject_HEAD_INIT (NULL, 0)
     37      1.1  christos };
     38      1.1  christos 
     39      1.1  christos /* Python RecordFunctionSegment type.  */
     40      1.1  christos 
     41      1.1  christos PyTypeObject recpy_func_type = {
     42      1.1  christos   PyVarObject_HEAD_INIT (NULL, 0)
     43      1.1  christos };
     44      1.1  christos 
     45      1.1  christos /* Python RecordGap type.  */
     46      1.1  christos 
     47  1.1.1.4  christos static PyTypeObject recpy_gap_type = {
     48      1.1  christos   PyVarObject_HEAD_INIT (NULL, 0)
     49      1.1  christos };
     50      1.1  christos 
     51      1.1  christos /* Python RecordGap object.  */
     52  1.1.1.4  christos struct recpy_gap_object
     53      1.1  christos {
     54      1.1  christos   PyObject_HEAD
     55      1.1  christos 
     56      1.1  christos   /* Reason code.  */
     57      1.1  christos   int reason_code;
     58      1.1  christos 
     59      1.1  christos   /* Reason message.  */
     60      1.1  christos   const char *reason_string;
     61      1.1  christos 
     62      1.1  christos   /* Element number.  */
     63      1.1  christos   Py_ssize_t number;
     64  1.1.1.4  christos };
     65      1.1  christos 
     66      1.1  christos /* Implementation of record.method.  */
     67      1.1  christos 
     68      1.1  christos static PyObject *
     69      1.1  christos recpy_method (PyObject *self, void* closure)
     70      1.1  christos {
     71      1.1  christos   const recpy_record_object * const obj = (recpy_record_object *) self;
     72      1.1  christos 
     73      1.1  christos   if (obj->method == RECORD_METHOD_FULL)
     74      1.1  christos     return recpy_full_method (self, closure);
     75      1.1  christos 
     76      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
     77      1.1  christos     return recpy_bt_method (self, closure);
     78      1.1  christos 
     79      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
     80      1.1  christos }
     81      1.1  christos 
     82      1.1  christos /* Implementation of record.format.  */
     83      1.1  christos 
     84      1.1  christos static PyObject *
     85      1.1  christos recpy_format (PyObject *self, void* closure)
     86      1.1  christos {
     87      1.1  christos   const recpy_record_object * const obj = (recpy_record_object *) self;
     88      1.1  christos 
     89      1.1  christos   if (obj->method == RECORD_METHOD_FULL)
     90      1.1  christos     return recpy_full_format (self, closure);
     91      1.1  christos 
     92      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
     93      1.1  christos     return recpy_bt_format (self, closure);
     94      1.1  christos 
     95      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
     96      1.1  christos }
     97      1.1  christos 
     98      1.1  christos /* Implementation of record.goto (instruction) -> None.  */
     99      1.1  christos 
    100      1.1  christos static PyObject *
    101      1.1  christos recpy_goto (PyObject *self, PyObject *value)
    102      1.1  christos {
    103      1.1  christos   const recpy_record_object * const obj = (recpy_record_object *) self;
    104      1.1  christos 
    105      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    106      1.1  christos     return recpy_bt_goto (self, value);
    107      1.1  christos 
    108      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    109      1.1  christos }
    110      1.1  christos 
    111      1.1  christos /* Implementation of record.replay_position [instruction]  */
    112      1.1  christos 
    113      1.1  christos static PyObject *
    114      1.1  christos recpy_replay_position (PyObject *self, void *closure)
    115      1.1  christos {
    116      1.1  christos   const recpy_record_object * const obj = (recpy_record_object *) self;
    117      1.1  christos 
    118      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    119      1.1  christos     return recpy_bt_replay_position (self, closure);
    120      1.1  christos 
    121      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    122      1.1  christos }
    123      1.1  christos 
    124      1.1  christos /* Implementation of record.instruction_history [list].  */
    125      1.1  christos 
    126      1.1  christos static PyObject *
    127      1.1  christos recpy_instruction_history (PyObject *self, void* closure)
    128      1.1  christos {
    129      1.1  christos   const recpy_record_object * const obj = (recpy_record_object *) self;
    130      1.1  christos 
    131      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    132      1.1  christos     return recpy_bt_instruction_history (self, closure);
    133      1.1  christos 
    134      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    135      1.1  christos }
    136      1.1  christos 
    137      1.1  christos /* Implementation of record.function_call_history [list].  */
    138      1.1  christos 
    139      1.1  christos static PyObject *
    140      1.1  christos recpy_function_call_history (PyObject *self, void* closure)
    141      1.1  christos {
    142      1.1  christos   const recpy_record_object * const obj = (recpy_record_object *) self;
    143      1.1  christos 
    144      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    145      1.1  christos     return recpy_bt_function_call_history (self, closure);
    146      1.1  christos 
    147      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    148      1.1  christos }
    149      1.1  christos 
    150      1.1  christos /* Implementation of record.begin [instruction].  */
    151      1.1  christos 
    152      1.1  christos static PyObject *
    153      1.1  christos recpy_begin (PyObject *self, void* closure)
    154      1.1  christos {
    155      1.1  christos   const recpy_record_object * const obj = (recpy_record_object *) self;
    156      1.1  christos 
    157      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    158      1.1  christos     return recpy_bt_begin (self, closure);
    159      1.1  christos 
    160      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    161      1.1  christos }
    162      1.1  christos 
    163      1.1  christos /* Implementation of record.end [instruction].  */
    164      1.1  christos 
    165      1.1  christos static PyObject *
    166      1.1  christos recpy_end (PyObject *self, void* closure)
    167      1.1  christos {
    168      1.1  christos   const recpy_record_object * const obj = (recpy_record_object *) self;
    169      1.1  christos 
    170      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    171      1.1  christos     return recpy_bt_end (self, closure);
    172      1.1  christos 
    173      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    174      1.1  christos }
    175      1.1  christos 
    176      1.1  christos /* Create a new gdb.RecordInstruction object.  */
    177      1.1  christos 
    178      1.1  christos PyObject *
    179  1.1.1.5  christos recpy_insn_new (thread_info *thread, enum record_method method,
    180  1.1.1.5  christos 		Py_ssize_t number)
    181      1.1  christos {
    182      1.1  christos   recpy_element_object * const obj = PyObject_New (recpy_element_object,
    183      1.1  christos 						   &recpy_insn_type);
    184      1.1  christos 
    185      1.1  christos   if (obj == NULL)
    186      1.1  christos    return NULL;
    187      1.1  christos 
    188  1.1.1.2  christos   obj->thread = thread;
    189      1.1  christos   obj->method = method;
    190      1.1  christos   obj->number = number;
    191      1.1  christos 
    192      1.1  christos   return (PyObject *) obj;
    193      1.1  christos }
    194      1.1  christos 
    195      1.1  christos /* Implementation of RecordInstruction.sal [gdb.Symtab_and_line].  */
    196      1.1  christos 
    197      1.1  christos static PyObject *
    198      1.1  christos recpy_insn_sal (PyObject *self, void *closure)
    199      1.1  christos {
    200      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    201      1.1  christos 
    202      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    203      1.1  christos     return recpy_bt_insn_sal (self, closure);
    204      1.1  christos 
    205      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    206      1.1  christos }
    207      1.1  christos 
    208      1.1  christos /* Implementation of RecordInstruction.pc [int].  */
    209      1.1  christos 
    210      1.1  christos static PyObject *
    211      1.1  christos recpy_insn_pc (PyObject *self, void *closure)
    212      1.1  christos {
    213      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    214      1.1  christos 
    215      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    216      1.1  christos     return recpy_bt_insn_pc (self, closure);
    217      1.1  christos 
    218      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    219      1.1  christos }
    220      1.1  christos 
    221      1.1  christos /* Implementation of RecordInstruction.data [buffer].  */
    222      1.1  christos 
    223      1.1  christos static PyObject *
    224      1.1  christos recpy_insn_data (PyObject *self, void *closure)
    225      1.1  christos {
    226      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    227      1.1  christos 
    228      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    229      1.1  christos     return recpy_bt_insn_data (self, closure);
    230      1.1  christos 
    231      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    232      1.1  christos }
    233      1.1  christos 
    234      1.1  christos /* Implementation of RecordInstruction.decoded [str].  */
    235      1.1  christos 
    236      1.1  christos static PyObject *
    237      1.1  christos recpy_insn_decoded (PyObject *self, void *closure)
    238      1.1  christos {
    239      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    240      1.1  christos 
    241      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    242      1.1  christos     return recpy_bt_insn_decoded (self, closure);
    243      1.1  christos 
    244      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    245      1.1  christos }
    246      1.1  christos 
    247      1.1  christos /* Implementation of RecordInstruction.size [int].  */
    248      1.1  christos 
    249      1.1  christos static PyObject *
    250      1.1  christos recpy_insn_size (PyObject *self, void *closure)
    251      1.1  christos {
    252      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    253      1.1  christos 
    254      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    255      1.1  christos     return recpy_bt_insn_size (self, closure);
    256      1.1  christos 
    257      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    258      1.1  christos }
    259      1.1  christos 
    260      1.1  christos /* Implementation of RecordInstruction.is_speculative [bool].  */
    261      1.1  christos 
    262      1.1  christos static PyObject *
    263      1.1  christos recpy_insn_is_speculative (PyObject *self, void *closure)
    264      1.1  christos {
    265      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    266      1.1  christos 
    267      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    268      1.1  christos     return recpy_bt_insn_is_speculative (self, closure);
    269      1.1  christos 
    270      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    271      1.1  christos }
    272      1.1  christos 
    273      1.1  christos /* Create a new gdb.RecordFunctionSegment object.  */
    274      1.1  christos 
    275      1.1  christos PyObject *
    276  1.1.1.5  christos recpy_func_new (thread_info *thread, enum record_method method,
    277  1.1.1.5  christos 		Py_ssize_t number)
    278      1.1  christos {
    279      1.1  christos   recpy_element_object * const obj = PyObject_New (recpy_element_object,
    280      1.1  christos 						   &recpy_func_type);
    281      1.1  christos 
    282      1.1  christos   if (obj == NULL)
    283      1.1  christos    return NULL;
    284      1.1  christos 
    285  1.1.1.2  christos   obj->thread = thread;
    286      1.1  christos   obj->method = method;
    287      1.1  christos   obj->number = number;
    288      1.1  christos 
    289      1.1  christos   return (PyObject *) obj;
    290      1.1  christos }
    291      1.1  christos 
    292      1.1  christos /* Implementation of RecordFunctionSegment.level [int].  */
    293      1.1  christos 
    294      1.1  christos static PyObject *
    295      1.1  christos recpy_func_level (PyObject *self, void *closure)
    296      1.1  christos {
    297      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    298      1.1  christos 
    299      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    300      1.1  christos     return recpy_bt_func_level (self, closure);
    301      1.1  christos 
    302      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    303      1.1  christos }
    304      1.1  christos 
    305      1.1  christos /* Implementation of RecordFunctionSegment.symbol [gdb.Symbol].  */
    306      1.1  christos 
    307      1.1  christos static PyObject *
    308      1.1  christos recpy_func_symbol (PyObject *self, void *closure)
    309      1.1  christos {
    310      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    311      1.1  christos 
    312      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    313      1.1  christos     return recpy_bt_func_symbol (self, closure);
    314      1.1  christos 
    315      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    316      1.1  christos }
    317      1.1  christos 
    318      1.1  christos /* Implementation of RecordFunctionSegment.instructions [list].  */
    319      1.1  christos 
    320      1.1  christos static PyObject *
    321      1.1  christos recpy_func_instructions (PyObject *self, void *closure)
    322      1.1  christos {
    323      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    324      1.1  christos 
    325      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    326      1.1  christos     return recpy_bt_func_instructions (self, closure);
    327      1.1  christos 
    328      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    329      1.1  christos }
    330      1.1  christos 
    331      1.1  christos /* Implementation of RecordFunctionSegment.up [RecordFunctionSegment].  */
    332      1.1  christos 
    333      1.1  christos static PyObject *
    334      1.1  christos recpy_func_up (PyObject *self, void *closure)
    335      1.1  christos {
    336      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    337      1.1  christos 
    338      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    339      1.1  christos     return recpy_bt_func_up (self, closure);
    340      1.1  christos 
    341      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    342      1.1  christos }
    343      1.1  christos 
    344      1.1  christos /* Implementation of RecordFunctionSegment.prev [RecordFunctionSegment].  */
    345      1.1  christos 
    346      1.1  christos static PyObject *
    347      1.1  christos recpy_func_prev (PyObject *self, void *closure)
    348      1.1  christos {
    349      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    350      1.1  christos 
    351      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    352      1.1  christos     return recpy_bt_func_prev (self, closure);
    353      1.1  christos 
    354      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    355      1.1  christos }
    356      1.1  christos 
    357      1.1  christos /* Implementation of RecordFunctionSegment.next [RecordFunctionSegment].  */
    358      1.1  christos 
    359      1.1  christos static PyObject *
    360      1.1  christos recpy_func_next (PyObject *self, void *closure)
    361      1.1  christos {
    362      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    363      1.1  christos 
    364      1.1  christos   if (obj->method == RECORD_METHOD_BTRACE)
    365      1.1  christos     return recpy_bt_func_next (self, closure);
    366      1.1  christos 
    367      1.1  christos   return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
    368      1.1  christos }
    369      1.1  christos 
    370      1.1  christos /* Implementation of RecordInstruction.number [int] and
    371      1.1  christos    RecordFunctionSegment.number [int].  */
    372      1.1  christos 
    373      1.1  christos static PyObject *
    374      1.1  christos recpy_element_number (PyObject *self, void* closure)
    375      1.1  christos {
    376      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    377      1.1  christos 
    378  1.1.1.4  christos   return gdb_py_object_from_longest (obj->number).release ();
    379      1.1  christos }
    380      1.1  christos 
    381      1.1  christos /* Implementation of RecordInstruction.__hash__ [int] and
    382      1.1  christos    RecordFunctionSegment.__hash__ [int].  */
    383      1.1  christos 
    384      1.1  christos static Py_hash_t
    385      1.1  christos recpy_element_hash (PyObject *self)
    386      1.1  christos {
    387      1.1  christos   const recpy_element_object * const obj = (recpy_element_object *) self;
    388      1.1  christos 
    389      1.1  christos   return obj->number;
    390      1.1  christos }
    391      1.1  christos 
    392      1.1  christos /* Implementation of operator == and != of RecordInstruction and
    393      1.1  christos    RecordFunctionSegment.  */
    394      1.1  christos 
    395      1.1  christos static PyObject *
    396      1.1  christos recpy_element_richcompare (PyObject *self, PyObject *other, int op)
    397      1.1  christos {
    398      1.1  christos   const recpy_element_object * const obj1 = (recpy_element_object *) self;
    399      1.1  christos   const recpy_element_object * const obj2 = (recpy_element_object *) other;
    400      1.1  christos 
    401      1.1  christos   if (Py_TYPE (self) != Py_TYPE (other))
    402      1.1  christos     {
    403      1.1  christos       Py_INCREF (Py_NotImplemented);
    404      1.1  christos       return Py_NotImplemented;
    405      1.1  christos     }
    406      1.1  christos 
    407      1.1  christos   switch (op)
    408      1.1  christos   {
    409      1.1  christos     case Py_EQ:
    410  1.1.1.2  christos       if (obj1->thread == obj2->thread
    411      1.1  christos 	  && obj1->method == obj2->method
    412      1.1  christos 	  && obj1->number == obj2->number)
    413      1.1  christos 	Py_RETURN_TRUE;
    414      1.1  christos       else
    415      1.1  christos 	Py_RETURN_FALSE;
    416      1.1  christos 
    417      1.1  christos     case Py_NE:
    418  1.1.1.2  christos       if (obj1->thread != obj2->thread
    419      1.1  christos 	  || obj1->method != obj2->method
    420      1.1  christos 	  || obj1->number != obj2->number)
    421      1.1  christos 	Py_RETURN_TRUE;
    422      1.1  christos       else
    423      1.1  christos 	Py_RETURN_FALSE;
    424      1.1  christos 
    425      1.1  christos     default:
    426      1.1  christos       break;
    427      1.1  christos   }
    428      1.1  christos 
    429      1.1  christos   Py_INCREF (Py_NotImplemented);
    430      1.1  christos   return Py_NotImplemented;
    431      1.1  christos }
    432      1.1  christos 
    433      1.1  christos /* Create a new gdb.RecordGap object.  */
    434      1.1  christos 
    435      1.1  christos PyObject *
    436      1.1  christos recpy_gap_new (int reason_code, const char *reason_string, Py_ssize_t number)
    437      1.1  christos {
    438      1.1  christos   recpy_gap_object * const obj = PyObject_New (recpy_gap_object,
    439      1.1  christos 					       &recpy_gap_type);
    440      1.1  christos 
    441      1.1  christos   if (obj == NULL)
    442      1.1  christos    return NULL;
    443      1.1  christos 
    444      1.1  christos   obj->reason_code = reason_code;
    445      1.1  christos   obj->reason_string = reason_string;
    446      1.1  christos   obj->number = number;
    447      1.1  christos 
    448      1.1  christos   return (PyObject *) obj;
    449      1.1  christos }
    450      1.1  christos 
    451      1.1  christos /* Implementation of RecordGap.number [int].  */
    452      1.1  christos 
    453      1.1  christos static PyObject *
    454      1.1  christos recpy_gap_number (PyObject *self, void *closure)
    455      1.1  christos {
    456      1.1  christos   const recpy_gap_object * const obj = (const recpy_gap_object *) self;
    457      1.1  christos 
    458  1.1.1.4  christos   return gdb_py_object_from_longest (obj->number).release ();
    459      1.1  christos }
    460      1.1  christos 
    461      1.1  christos /* Implementation of RecordGap.error_code [int].  */
    462      1.1  christos 
    463      1.1  christos static PyObject *
    464      1.1  christos recpy_gap_reason_code (PyObject *self, void *closure)
    465      1.1  christos {
    466      1.1  christos   const recpy_gap_object * const obj = (const recpy_gap_object *) self;
    467      1.1  christos 
    468  1.1.1.4  christos   return gdb_py_object_from_longest (obj->reason_code).release ();
    469      1.1  christos }
    470      1.1  christos 
    471      1.1  christos /* Implementation of RecordGap.error_string [str].  */
    472      1.1  christos 
    473      1.1  christos static PyObject *
    474      1.1  christos recpy_gap_reason_string (PyObject *self, void *closure)
    475      1.1  christos {
    476      1.1  christos   const recpy_gap_object * const obj = (const recpy_gap_object *) self;
    477      1.1  christos 
    478  1.1.1.4  christos   return PyUnicode_FromString (obj->reason_string);
    479      1.1  christos }
    480      1.1  christos 
    481      1.1  christos /* Record method list.  */
    482      1.1  christos 
    483      1.1  christos static PyMethodDef recpy_record_methods[] = {
    484      1.1  christos   { "goto", recpy_goto, METH_VARARGS,
    485      1.1  christos     "goto (instruction|function_call) -> None.\n\
    486      1.1  christos Rewind to given location."},
    487      1.1  christos   { NULL }
    488      1.1  christos };
    489      1.1  christos 
    490      1.1  christos /* Record member list.  */
    491      1.1  christos 
    492      1.1  christos static gdb_PyGetSetDef recpy_record_getset[] = {
    493      1.1  christos   { "method", recpy_method, NULL, "Current recording method.", NULL },
    494      1.1  christos   { "format", recpy_format, NULL, "Current recording format.", NULL },
    495      1.1  christos   { "replay_position", recpy_replay_position, NULL, "Current replay position.",
    496      1.1  christos     NULL },
    497      1.1  christos   { "instruction_history", recpy_instruction_history, NULL,
    498      1.1  christos     "List of instructions in current recording.", NULL },
    499      1.1  christos   { "function_call_history", recpy_function_call_history, NULL,
    500      1.1  christos     "List of function calls in current recording.", NULL },
    501      1.1  christos   { "begin", recpy_begin, NULL,
    502      1.1  christos     "First instruction in current recording.", NULL },
    503      1.1  christos   { "end", recpy_end, NULL,
    504      1.1  christos     "One past the last instruction in current recording.  This is typically \
    505      1.1  christos the current instruction and is used for e.g. record.goto (record.end).", NULL },
    506      1.1  christos   { NULL }
    507      1.1  christos };
    508      1.1  christos 
    509      1.1  christos /* RecordInstruction member list.  */
    510      1.1  christos 
    511      1.1  christos static gdb_PyGetSetDef recpy_insn_getset[] = {
    512      1.1  christos   { "number", recpy_element_number, NULL, "instruction number", NULL},
    513      1.1  christos   { "sal", recpy_insn_sal, NULL, "associated symbol and line", NULL},
    514      1.1  christos   { "pc", recpy_insn_pc, NULL, "instruction address", NULL},
    515      1.1  christos   { "data", recpy_insn_data, NULL, "raw instruction data", NULL},
    516      1.1  christos   { "decoded", recpy_insn_decoded, NULL, "decoded instruction", NULL},
    517      1.1  christos   { "size", recpy_insn_size, NULL, "instruction size in byte", NULL},
    518      1.1  christos   { "is_speculative", recpy_insn_is_speculative, NULL, "if the instruction was \
    519      1.1  christos   executed speculatively", NULL},
    520      1.1  christos   { NULL }
    521      1.1  christos };
    522      1.1  christos 
    523      1.1  christos /* RecordFunctionSegment member list.  */
    524      1.1  christos 
    525      1.1  christos static gdb_PyGetSetDef recpy_func_getset[] = {
    526      1.1  christos   { "number", recpy_element_number, NULL, "function segment number", NULL},
    527      1.1  christos   { "level", recpy_func_level, NULL, "call stack level", NULL},
    528      1.1  christos   { "symbol", recpy_func_symbol, NULL, "associated line and symbol", NULL},
    529      1.1  christos   { "instructions", recpy_func_instructions, NULL, "list of instructions in \
    530      1.1  christos this function segment", NULL},
    531      1.1  christos   { "up", recpy_func_up, NULL, "caller or returned-to function segment", NULL},
    532      1.1  christos   { "prev", recpy_func_prev, NULL, "previous segment of this function", NULL},
    533      1.1  christos   { "next", recpy_func_next, NULL, "next segment of this function", NULL},
    534      1.1  christos   { NULL }
    535      1.1  christos };
    536      1.1  christos 
    537      1.1  christos /* RecordGap member list.  */
    538      1.1  christos 
    539      1.1  christos static gdb_PyGetSetDef recpy_gap_getset[] = {
    540      1.1  christos   { "number", recpy_gap_number, NULL, "element number", NULL},
    541      1.1  christos   { "reason_code", recpy_gap_reason_code, NULL, "reason code", NULL},
    542      1.1  christos   { "reason_string", recpy_gap_reason_string, NULL, "reason string", NULL},
    543      1.1  christos   { NULL }
    544      1.1  christos };
    545      1.1  christos 
    546      1.1  christos /* Sets up the record API in the gdb module.  */
    547      1.1  christos 
    548  1.1.1.5  christos static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
    549      1.1  christos gdbpy_initialize_record (void)
    550      1.1  christos {
    551      1.1  christos   recpy_record_type.tp_new = PyType_GenericNew;
    552      1.1  christos   recpy_record_type.tp_flags = Py_TPFLAGS_DEFAULT;
    553      1.1  christos   recpy_record_type.tp_basicsize = sizeof (recpy_record_object);
    554      1.1  christos   recpy_record_type.tp_name = "gdb.Record";
    555      1.1  christos   recpy_record_type.tp_doc = "GDB record object";
    556      1.1  christos   recpy_record_type.tp_methods = recpy_record_methods;
    557      1.1  christos   recpy_record_type.tp_getset = recpy_record_getset;
    558      1.1  christos 
    559      1.1  christos   recpy_insn_type.tp_new = PyType_GenericNew;
    560      1.1  christos   recpy_insn_type.tp_flags = Py_TPFLAGS_DEFAULT;
    561      1.1  christos   recpy_insn_type.tp_basicsize = sizeof (recpy_element_object);
    562      1.1  christos   recpy_insn_type.tp_name = "gdb.RecordInstruction";
    563      1.1  christos   recpy_insn_type.tp_doc = "GDB recorded instruction object";
    564      1.1  christos   recpy_insn_type.tp_getset = recpy_insn_getset;
    565      1.1  christos   recpy_insn_type.tp_richcompare = recpy_element_richcompare;
    566      1.1  christos   recpy_insn_type.tp_hash = recpy_element_hash;
    567  1.1.1.4  christos   recpy_insn_type.tp_base = py_insn_get_insn_type ();
    568      1.1  christos 
    569      1.1  christos   recpy_func_type.tp_new = PyType_GenericNew;
    570      1.1  christos   recpy_func_type.tp_flags = Py_TPFLAGS_DEFAULT;
    571      1.1  christos   recpy_func_type.tp_basicsize = sizeof (recpy_element_object);
    572      1.1  christos   recpy_func_type.tp_name = "gdb.RecordFunctionSegment";
    573      1.1  christos   recpy_func_type.tp_doc = "GDB record function segment object";
    574      1.1  christos   recpy_func_type.tp_getset = recpy_func_getset;
    575      1.1  christos   recpy_func_type.tp_richcompare = recpy_element_richcompare;
    576      1.1  christos   recpy_func_type.tp_hash = recpy_element_hash;
    577      1.1  christos 
    578      1.1  christos   recpy_gap_type.tp_new = PyType_GenericNew;
    579      1.1  christos   recpy_gap_type.tp_flags = Py_TPFLAGS_DEFAULT;
    580      1.1  christos   recpy_gap_type.tp_basicsize = sizeof (recpy_gap_object);
    581      1.1  christos   recpy_gap_type.tp_name = "gdb.RecordGap";
    582      1.1  christos   recpy_gap_type.tp_doc = "GDB recorded gap object";
    583      1.1  christos   recpy_gap_type.tp_getset = recpy_gap_getset;
    584      1.1  christos 
    585      1.1  christos   if (PyType_Ready (&recpy_record_type) < 0
    586      1.1  christos       || PyType_Ready (&recpy_insn_type) < 0
    587      1.1  christos       || PyType_Ready (&recpy_func_type) < 0
    588      1.1  christos       || PyType_Ready (&recpy_gap_type) < 0)
    589      1.1  christos     return -1;
    590      1.1  christos   else
    591      1.1  christos     return 0;
    592      1.1  christos }
    593      1.1  christos 
    594      1.1  christos /* Implementation of gdb.start_recording (method) -> gdb.Record.  */
    595      1.1  christos 
    596      1.1  christos PyObject *
    597      1.1  christos gdbpy_start_recording (PyObject *self, PyObject *args)
    598      1.1  christos {
    599      1.1  christos   const char *method = NULL;
    600      1.1  christos   const char *format = NULL;
    601      1.1  christos   PyObject *ret = NULL;
    602      1.1  christos 
    603      1.1  christos   if (!PyArg_ParseTuple (args, "|ss", &method, &format))
    604      1.1  christos     return NULL;
    605      1.1  christos 
    606  1.1.1.3  christos   try
    607      1.1  christos     {
    608      1.1  christos       record_start (method, format, 0);
    609      1.1  christos       ret = gdbpy_current_recording (self, args);
    610      1.1  christos     }
    611  1.1.1.3  christos   catch (const gdb_exception &except)
    612      1.1  christos     {
    613      1.1  christos       gdbpy_convert_exception (except);
    614      1.1  christos     }
    615      1.1  christos 
    616      1.1  christos   return ret;
    617      1.1  christos }
    618      1.1  christos 
    619      1.1  christos /* Implementation of gdb.current_recording (self) -> gdb.Record.  */
    620      1.1  christos 
    621      1.1  christos PyObject *
    622      1.1  christos gdbpy_current_recording (PyObject *self, PyObject *args)
    623      1.1  christos {
    624      1.1  christos   recpy_record_object *ret = NULL;
    625      1.1  christos 
    626      1.1  christos   if (find_record_target () == NULL)
    627      1.1  christos     Py_RETURN_NONE;
    628      1.1  christos 
    629      1.1  christos   ret = PyObject_New (recpy_record_object, &recpy_record_type);
    630  1.1.1.2  christos   ret->thread = inferior_thread ();
    631  1.1.1.2  christos   ret->method = target_record_method (ret->thread->ptid);
    632      1.1  christos 
    633      1.1  christos   return (PyObject *) ret;
    634      1.1  christos }
    635      1.1  christos 
    636      1.1  christos /* Implementation of gdb.stop_recording (self) -> None.  */
    637      1.1  christos 
    638      1.1  christos PyObject *
    639      1.1  christos gdbpy_stop_recording (PyObject *self, PyObject *args)
    640      1.1  christos {
    641  1.1.1.3  christos   try
    642      1.1  christos     {
    643      1.1  christos       record_stop (0);
    644      1.1  christos     }
    645  1.1.1.3  christos   catch (const gdb_exception &except)
    646      1.1  christos     {
    647  1.1.1.2  christos       GDB_PY_HANDLE_EXCEPTION (except);
    648      1.1  christos     }
    649      1.1  christos 
    650  1.1.1.2  christos   Py_RETURN_NONE;
    651      1.1  christos }
    652  1.1.1.5  christos 
    653  1.1.1.5  christos GDBPY_INITIALIZE_FILE (gdbpy_initialize_record);
    654