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