1 /* Python interface to inferiors. 2 3 Copyright (C) 2009-2012 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "defs.h" 21 #include "exceptions.h" 22 #include "gdbcore.h" 23 #include "gdbthread.h" 24 #include "inferior.h" 25 #include "objfiles.h" 26 #include "observer.h" 27 #include "python-internal.h" 28 #include "arch-utils.h" 29 #include "language.h" 30 #include "gdb_signals.h" 31 #include "py-event.h" 32 #include "py-stopevent.h" 33 34 struct threadlist_entry { 35 thread_object *thread_obj; 36 struct threadlist_entry *next; 37 }; 38 39 typedef struct 40 { 41 PyObject_HEAD 42 43 /* The inferior we represent. */ 44 struct inferior *inferior; 45 46 /* thread_object instances under this inferior. This list owns a 47 reference to each object it contains. */ 48 struct threadlist_entry *threads; 49 50 /* Number of threads in the list. */ 51 int nthreads; 52 } inferior_object; 53 54 static PyTypeObject inferior_object_type; 55 56 static const struct inferior_data *infpy_inf_data_key; 57 58 typedef struct { 59 PyObject_HEAD 60 void *buffer; 61 62 /* These are kept just for mbpy_str. */ 63 CORE_ADDR addr; 64 CORE_ADDR length; 65 } membuf_object; 66 67 static PyTypeObject membuf_object_type; 68 69 /* Require that INFERIOR be a valid inferior ID. */ 70 #define INFPY_REQUIRE_VALID(Inferior) \ 71 do { \ 72 if (!Inferior->inferior) \ 73 { \ 74 PyErr_SetString (PyExc_RuntimeError, \ 75 _("Inferior no longer exists.")); \ 76 return NULL; \ 77 } \ 78 } while (0) 79 80 static void 81 python_on_normal_stop (struct bpstats *bs, int print_frame) 82 { 83 struct cleanup *cleanup; 84 enum target_signal stop_signal; 85 86 if (!find_thread_ptid (inferior_ptid)) 87 return; 88 89 stop_signal = inferior_thread ()->suspend.stop_signal; 90 91 cleanup = ensure_python_env (get_current_arch (), current_language); 92 93 if (emit_stop_event (bs, stop_signal) < 0) 94 gdbpy_print_stack (); 95 96 do_cleanups (cleanup); 97 } 98 99 static void 100 python_on_resume (ptid_t ptid) 101 { 102 struct cleanup *cleanup; 103 104 cleanup = ensure_python_env (target_gdbarch, current_language); 105 106 if (emit_continue_event (ptid) < 0) 107 gdbpy_print_stack (); 108 109 do_cleanups (cleanup); 110 } 111 112 static void 113 python_inferior_exit (struct inferior *inf) 114 { 115 struct cleanup *cleanup; 116 const LONGEST *exit_code = NULL; 117 118 cleanup = ensure_python_env (target_gdbarch, current_language); 119 120 if (inf->has_exit_code) 121 exit_code = &inf->exit_code; 122 123 if (emit_exited_event (exit_code, inf) < 0) 124 gdbpy_print_stack (); 125 126 do_cleanups (cleanup); 127 } 128 129 /* Callback used to notify Python listeners about new objfiles loaded in the 130 inferior. */ 131 132 static void 133 python_new_objfile (struct objfile *objfile) 134 { 135 struct cleanup *cleanup; 136 137 if (objfile == NULL) 138 return; 139 140 cleanup = ensure_python_env (get_objfile_arch (objfile), current_language); 141 142 if (emit_new_objfile_event (objfile) < 0) 143 gdbpy_print_stack (); 144 145 do_cleanups (cleanup); 146 } 147 148 /* Return a reference to the Python object of type Inferior 149 representing INFERIOR. If the object has already been created, 150 return it and increment the reference count, otherwise, create it. 151 Return NULL on failure. */ 152 PyObject * 153 inferior_to_inferior_object (struct inferior *inferior) 154 { 155 inferior_object *inf_obj; 156 157 inf_obj = inferior_data (inferior, infpy_inf_data_key); 158 if (!inf_obj) 159 { 160 inf_obj = PyObject_New (inferior_object, &inferior_object_type); 161 if (!inf_obj) 162 return NULL; 163 164 inf_obj->inferior = inferior; 165 inf_obj->threads = NULL; 166 inf_obj->nthreads = 0; 167 168 set_inferior_data (inferior, infpy_inf_data_key, inf_obj); 169 170 } 171 else 172 Py_INCREF ((PyObject *)inf_obj); 173 174 return (PyObject *) inf_obj; 175 } 176 177 /* Finds the Python Inferior object for the given PID. Returns a 178 reference, or NULL if PID does not match any inferior object. */ 179 180 PyObject * 181 find_inferior_object (int pid) 182 { 183 struct inflist_entry *p; 184 struct inferior *inf = find_inferior_pid (pid); 185 186 if (inf) 187 return inferior_to_inferior_object (inf); 188 189 return NULL; 190 } 191 192 thread_object * 193 find_thread_object (ptid_t ptid) 194 { 195 int pid; 196 struct threadlist_entry *thread; 197 PyObject *inf_obj; 198 thread_object *found = NULL; 199 200 pid = PIDGET (ptid); 201 if (pid == 0) 202 return NULL; 203 204 inf_obj = find_inferior_object (pid); 205 206 if (! inf_obj) 207 return NULL; 208 209 for (thread = ((inferior_object *)inf_obj)->threads; thread; 210 thread = thread->next) 211 if (ptid_equal (thread->thread_obj->thread->ptid, ptid)) 212 { 213 found = thread->thread_obj; 214 break; 215 } 216 217 Py_DECREF (inf_obj); 218 219 if (found) 220 return found; 221 222 return NULL; 223 } 224 225 static void 226 add_thread_object (struct thread_info *tp) 227 { 228 struct cleanup *cleanup; 229 thread_object *thread_obj; 230 inferior_object *inf_obj; 231 struct threadlist_entry *entry; 232 233 cleanup = ensure_python_env (python_gdbarch, python_language); 234 235 thread_obj = create_thread_object (tp); 236 if (!thread_obj) 237 { 238 gdbpy_print_stack (); 239 do_cleanups (cleanup); 240 return; 241 } 242 243 inf_obj = (inferior_object *) thread_obj->inf_obj; 244 245 entry = xmalloc (sizeof (struct threadlist_entry)); 246 entry->thread_obj = thread_obj; 247 entry->next = inf_obj->threads; 248 249 inf_obj->threads = entry; 250 inf_obj->nthreads++; 251 252 do_cleanups (cleanup); 253 } 254 255 static void 256 delete_thread_object (struct thread_info *tp, int ignore) 257 { 258 struct cleanup *cleanup; 259 inferior_object *inf_obj; 260 thread_object *thread_obj; 261 struct threadlist_entry **entry, *tmp; 262 263 cleanup = ensure_python_env (python_gdbarch, python_language); 264 265 inf_obj = (inferior_object *) find_inferior_object (PIDGET(tp->ptid)); 266 if (!inf_obj) 267 { 268 do_cleanups (cleanup); 269 return; 270 } 271 272 /* Find thread entry in its inferior's thread_list. */ 273 for (entry = &inf_obj->threads; *entry != NULL; entry = 274 &(*entry)->next) 275 if ((*entry)->thread_obj->thread == tp) 276 break; 277 278 if (!*entry) 279 { 280 Py_DECREF (inf_obj); 281 do_cleanups (cleanup); 282 return; 283 } 284 285 tmp = *entry; 286 tmp->thread_obj->thread = NULL; 287 288 *entry = (*entry)->next; 289 inf_obj->nthreads--; 290 291 Py_DECREF (tmp->thread_obj); 292 Py_DECREF (inf_obj); 293 xfree (tmp); 294 295 do_cleanups (cleanup); 296 } 297 298 static PyObject * 299 infpy_threads (PyObject *self, PyObject *args) 300 { 301 int i; 302 struct threadlist_entry *entry; 303 inferior_object *inf_obj = (inferior_object *) self; 304 PyObject *tuple; 305 306 INFPY_REQUIRE_VALID (inf_obj); 307 308 tuple = PyTuple_New (inf_obj->nthreads); 309 if (!tuple) 310 return NULL; 311 312 for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads; 313 i++, entry = entry->next) 314 { 315 Py_INCREF (entry->thread_obj); 316 PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->thread_obj); 317 } 318 319 return tuple; 320 } 321 322 static PyObject * 323 infpy_get_num (PyObject *self, void *closure) 324 { 325 inferior_object *inf = (inferior_object *) self; 326 327 INFPY_REQUIRE_VALID (inf); 328 329 return PyLong_FromLong (inf->inferior->num); 330 } 331 332 static PyObject * 333 infpy_get_pid (PyObject *self, void *closure) 334 { 335 inferior_object *inf = (inferior_object *) self; 336 337 INFPY_REQUIRE_VALID (inf); 338 339 return PyLong_FromLong (inf->inferior->pid); 340 } 341 342 static PyObject * 343 infpy_get_was_attached (PyObject *self, void *closure) 344 { 345 inferior_object *inf = (inferior_object *) self; 346 347 INFPY_REQUIRE_VALID (inf); 348 if (inf->inferior->attach_flag) 349 Py_RETURN_TRUE; 350 Py_RETURN_FALSE; 351 } 352 353 static int 354 build_inferior_list (struct inferior *inf, void *arg) 355 { 356 PyObject *list = arg; 357 PyObject *inferior = inferior_to_inferior_object (inf); 358 int success = 0; 359 360 if (! inferior) 361 return 0; 362 363 success = PyList_Append (list, inferior); 364 Py_DECREF (inferior); 365 366 if (success) 367 return 1; 368 369 return 0; 370 } 371 372 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...). 373 Returns a tuple of all inferiors. */ 374 PyObject * 375 gdbpy_inferiors (PyObject *unused, PyObject *unused2) 376 { 377 PyObject *list, *tuple; 378 379 list = PyList_New (0); 380 if (!list) 381 return NULL; 382 383 if (iterate_over_inferiors (build_inferior_list, list)) 384 { 385 Py_DECREF (list); 386 return NULL; 387 } 388 389 tuple = PyList_AsTuple (list); 390 Py_DECREF (list); 391 392 return tuple; 393 } 394 395 /* Membuf and memory manipulation. */ 396 397 /* Implementation of gdb.read_memory (address, length). 398 Returns a Python buffer object with LENGTH bytes of the inferior's 399 memory at ADDRESS. Both arguments are integers. Returns NULL on error, 400 with a python exception set. */ 401 static PyObject * 402 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw) 403 { 404 int error = 0; 405 CORE_ADDR addr, length; 406 void *buffer = NULL; 407 membuf_object *membuf_obj; 408 PyObject *addr_obj, *length_obj; 409 struct cleanup *cleanups; 410 volatile struct gdb_exception except; 411 static char *keywords[] = { "address", "length", NULL }; 412 413 if (! PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords, 414 &addr_obj, &length_obj)) 415 return NULL; 416 417 cleanups = make_cleanup (null_cleanup, NULL); 418 419 TRY_CATCH (except, RETURN_MASK_ALL) 420 { 421 if (!get_addr_from_python (addr_obj, &addr) 422 || !get_addr_from_python (length_obj, &length)) 423 { 424 error = 1; 425 break; 426 } 427 428 buffer = xmalloc (length); 429 make_cleanup (xfree, buffer); 430 431 read_memory (addr, buffer, length); 432 } 433 if (except.reason < 0) 434 { 435 do_cleanups (cleanups); 436 GDB_PY_HANDLE_EXCEPTION (except); 437 } 438 439 if (error) 440 { 441 do_cleanups (cleanups); 442 return NULL; 443 } 444 445 membuf_obj = PyObject_New (membuf_object, &membuf_object_type); 446 if (membuf_obj == NULL) 447 { 448 PyErr_SetString (PyExc_MemoryError, 449 _("Could not allocate memory buffer object.")); 450 do_cleanups (cleanups); 451 return NULL; 452 } 453 454 discard_cleanups (cleanups); 455 456 membuf_obj->buffer = buffer; 457 membuf_obj->addr = addr; 458 membuf_obj->length = length; 459 460 return PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0, 461 Py_END_OF_BUFFER); 462 } 463 464 /* Implementation of gdb.write_memory (address, buffer [, length]). 465 Writes the contents of BUFFER (a Python object supporting the read 466 buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH 467 bytes from BUFFER, or its entire contents if the argument is not 468 provided. The function returns nothing. Returns NULL on error, with 469 a python exception set. */ 470 static PyObject * 471 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw) 472 { 473 Py_ssize_t buf_len; 474 int error = 0; 475 const char *buffer; 476 CORE_ADDR addr, length; 477 PyObject *addr_obj, *length_obj = NULL; 478 volatile struct gdb_exception except; 479 static char *keywords[] = { "address", "buffer", "length", NULL }; 480 481 482 if (! PyArg_ParseTupleAndKeywords (args, kw, "Os#|O", keywords, 483 &addr_obj, &buffer, &buf_len, 484 &length_obj)) 485 return NULL; 486 487 TRY_CATCH (except, RETURN_MASK_ALL) 488 { 489 if (!get_addr_from_python (addr_obj, &addr)) 490 { 491 error = 1; 492 break; 493 } 494 495 if (!length_obj) 496 length = buf_len; 497 else if (!get_addr_from_python (length_obj, &length)) 498 { 499 error = 1; 500 break; 501 } 502 write_memory (addr, buffer, length); 503 } 504 GDB_PY_HANDLE_EXCEPTION (except); 505 506 if (error) 507 return NULL; 508 509 Py_RETURN_NONE; 510 } 511 512 /* Destructor of Membuf objects. */ 513 static void 514 mbpy_dealloc (PyObject *self) 515 { 516 xfree (((membuf_object *) self)->buffer); 517 self->ob_type->tp_free (self); 518 } 519 520 /* Return a description of the Membuf object. */ 521 static PyObject * 522 mbpy_str (PyObject *self) 523 { 524 membuf_object *membuf_obj = (membuf_object *) self; 525 526 return PyString_FromFormat (_("Memory buffer for address %s, \ 527 which is %s bytes long."), 528 paddress (python_gdbarch, membuf_obj->addr), 529 pulongest (membuf_obj->length)); 530 } 531 532 static Py_ssize_t 533 get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr) 534 { 535 membuf_object *membuf_obj = (membuf_object *) self; 536 537 if (segment) 538 { 539 PyErr_SetString (PyExc_SystemError, 540 _("The memory buffer supports only one segment.")); 541 return -1; 542 } 543 544 *ptrptr = membuf_obj->buffer; 545 546 return membuf_obj->length; 547 } 548 549 static Py_ssize_t 550 get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr) 551 { 552 return get_read_buffer (self, segment, ptrptr); 553 } 554 555 static Py_ssize_t 556 get_seg_count (PyObject *self, Py_ssize_t *lenp) 557 { 558 if (lenp) 559 *lenp = ((membuf_object *) self)->length; 560 561 return 1; 562 } 563 564 static Py_ssize_t 565 get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr) 566 { 567 void *ptr = NULL; 568 Py_ssize_t ret; 569 570 ret = get_read_buffer (self, segment, &ptr); 571 *ptrptr = (char *) ptr; 572 573 return ret; 574 } 575 576 /* Implementation of 577 gdb.search_memory (address, length, pattern). ADDRESS is the 578 address to start the search. LENGTH specifies the scope of the 579 search from ADDRESS. PATTERN is the pattern to search for (and 580 must be a Python object supporting the buffer protocol). 581 Returns a Python Long object holding the address where the pattern 582 was located, or if the pattern was not found, returns None. Returns NULL 583 on error, with a python exception set. */ 584 static PyObject * 585 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw) 586 { 587 CORE_ADDR start_addr, length; 588 static char *keywords[] = { "address", "length", "pattern", NULL }; 589 PyObject *pattern, *start_addr_obj, *length_obj; 590 volatile struct gdb_exception except; 591 Py_ssize_t pattern_size; 592 const void *buffer; 593 CORE_ADDR found_addr; 594 int found = 0; 595 596 if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO", keywords, 597 &start_addr_obj, &length_obj, 598 &pattern)) 599 return NULL; 600 601 if (get_addr_from_python (start_addr_obj, &start_addr) 602 && get_addr_from_python (length_obj, &length)) 603 { 604 if (!length) 605 { 606 PyErr_SetString (PyExc_ValueError, 607 _("Search range is empty.")); 608 return NULL; 609 } 610 /* Watch for overflows. */ 611 else if (length > CORE_ADDR_MAX 612 || (start_addr + length - 1) < start_addr) 613 { 614 PyErr_SetString (PyExc_ValueError, 615 _("The search range is too large.")); 616 617 return NULL; 618 } 619 } 620 else 621 return NULL; 622 623 if (!PyObject_CheckReadBuffer (pattern)) 624 { 625 PyErr_SetString (PyExc_RuntimeError, 626 _("The pattern is not a Python buffer.")); 627 628 return NULL; 629 } 630 631 if (PyObject_AsReadBuffer (pattern, &buffer, &pattern_size) == -1) 632 return NULL; 633 634 TRY_CATCH (except, RETURN_MASK_ALL) 635 { 636 found = target_search_memory (start_addr, length, 637 buffer, pattern_size, 638 &found_addr); 639 } 640 GDB_PY_HANDLE_EXCEPTION (except); 641 642 if (found) 643 return PyLong_FromLong (found_addr); 644 else 645 Py_RETURN_NONE; 646 } 647 648 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean. 649 Returns True if this inferior object still exists in GDB. */ 650 651 static PyObject * 652 infpy_is_valid (PyObject *self, PyObject *args) 653 { 654 inferior_object *inf = (inferior_object *) self; 655 656 if (! inf->inferior) 657 Py_RETURN_FALSE; 658 659 Py_RETURN_TRUE; 660 } 661 662 static void 663 infpy_dealloc (PyObject *obj) 664 { 665 inferior_object *inf_obj = (inferior_object *) obj; 666 struct inferior *inf = inf_obj->inferior; 667 668 if (! inf) 669 return; 670 671 set_inferior_data (inf, infpy_inf_data_key, NULL); 672 } 673 674 /* Clear the INFERIOR pointer in an Inferior object and clear the 675 thread list. */ 676 static void 677 py_free_inferior (struct inferior *inf, void *datum) 678 { 679 680 struct cleanup *cleanup; 681 inferior_object *inf_obj = datum; 682 struct threadlist_entry *th_entry, *th_tmp; 683 684 cleanup = ensure_python_env (python_gdbarch, python_language); 685 686 inf_obj->inferior = NULL; 687 688 /* Deallocate threads list. */ 689 for (th_entry = inf_obj->threads; th_entry != NULL;) 690 { 691 Py_DECREF (th_entry->thread_obj); 692 693 th_tmp = th_entry; 694 th_entry = th_entry->next; 695 xfree (th_tmp); 696 } 697 698 inf_obj->nthreads = 0; 699 700 Py_DECREF ((PyObject *) inf_obj); 701 do_cleanups (cleanup); 702 } 703 704 /* Implementation of gdb.selected_inferior() -> gdb.Inferior. 705 Returns the current inferior object. */ 706 707 PyObject * 708 gdbpy_selected_inferior (PyObject *self, PyObject *args) 709 { 710 PyObject *inf_obj; 711 712 inf_obj = inferior_to_inferior_object (current_inferior ()); 713 Py_INCREF (inf_obj); 714 715 return inf_obj; 716 } 717 718 void 719 gdbpy_initialize_inferior (void) 720 { 721 if (PyType_Ready (&inferior_object_type) < 0) 722 return; 723 724 Py_INCREF (&inferior_object_type); 725 PyModule_AddObject (gdb_module, "Inferior", 726 (PyObject *) &inferior_object_type); 727 728 infpy_inf_data_key = 729 register_inferior_data_with_cleanup (py_free_inferior); 730 731 observer_attach_new_thread (add_thread_object); 732 observer_attach_thread_exit (delete_thread_object); 733 observer_attach_normal_stop (python_on_normal_stop); 734 observer_attach_target_resumed (python_on_resume); 735 observer_attach_inferior_exit (python_inferior_exit); 736 observer_attach_new_objfile (python_new_objfile); 737 738 membuf_object_type.tp_new = PyType_GenericNew; 739 if (PyType_Ready (&membuf_object_type) < 0) 740 return; 741 742 Py_INCREF (&membuf_object_type); 743 PyModule_AddObject (gdb_module, "Membuf", (PyObject *) 744 &membuf_object_type); 745 } 746 747 static PyGetSetDef inferior_object_getset[] = 748 { 749 { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL }, 750 { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.", 751 NULL }, 752 { "was_attached", infpy_get_was_attached, NULL, 753 "True if the inferior was created using 'attach'.", NULL }, 754 { NULL } 755 }; 756 757 static PyMethodDef inferior_object_methods[] = 758 { 759 { "is_valid", infpy_is_valid, METH_NOARGS, 760 "is_valid () -> Boolean.\n\ 761 Return true if this inferior is valid, false if not." }, 762 { "threads", infpy_threads, METH_NOARGS, 763 "Return all the threads of this inferior." }, 764 { "read_memory", (PyCFunction) infpy_read_memory, 765 METH_VARARGS | METH_KEYWORDS, 766 "read_memory (address, length) -> buffer\n\ 767 Return a buffer object for reading from the inferior's memory." }, 768 { "write_memory", (PyCFunction) infpy_write_memory, 769 METH_VARARGS | METH_KEYWORDS, 770 "write_memory (address, buffer [, length])\n\ 771 Write the given buffer object to the inferior's memory." }, 772 { "search_memory", (PyCFunction) infpy_search_memory, 773 METH_VARARGS | METH_KEYWORDS, 774 "search_memory (address, length, pattern) -> long\n\ 775 Return a long with the address of a match, or None." }, 776 { NULL } 777 }; 778 779 static PyTypeObject inferior_object_type = 780 { 781 PyObject_HEAD_INIT (NULL) 782 0, /* ob_size */ 783 "gdb.Inferior", /* tp_name */ 784 sizeof (inferior_object), /* tp_basicsize */ 785 0, /* tp_itemsize */ 786 infpy_dealloc, /* tp_dealloc */ 787 0, /* tp_print */ 788 0, /* tp_getattr */ 789 0, /* tp_setattr */ 790 0, /* tp_compare */ 791 0, /* tp_repr */ 792 0, /* tp_as_number */ 793 0, /* tp_as_sequence */ 794 0, /* tp_as_mapping */ 795 0, /* tp_hash */ 796 0, /* tp_call */ 797 0, /* tp_str */ 798 0, /* tp_getattro */ 799 0, /* tp_setattro */ 800 0, /* tp_as_buffer */ 801 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */ 802 "GDB inferior object", /* tp_doc */ 803 0, /* tp_traverse */ 804 0, /* tp_clear */ 805 0, /* tp_richcompare */ 806 0, /* tp_weaklistoffset */ 807 0, /* tp_iter */ 808 0, /* tp_iternext */ 809 inferior_object_methods, /* tp_methods */ 810 0, /* tp_members */ 811 inferior_object_getset, /* tp_getset */ 812 0, /* tp_base */ 813 0, /* tp_dict */ 814 0, /* tp_descr_get */ 815 0, /* tp_descr_set */ 816 0, /* tp_dictoffset */ 817 0, /* tp_init */ 818 0 /* tp_alloc */ 819 }; 820 821 /* Python doesn't provide a decent way to get compatibility here. */ 822 #if HAVE_LIBPYTHON2_4 823 #define CHARBUFFERPROC_NAME getcharbufferproc 824 #else 825 #define CHARBUFFERPROC_NAME charbufferproc 826 #endif 827 828 static PyBufferProcs buffer_procs = { 829 get_read_buffer, 830 get_write_buffer, 831 get_seg_count, 832 /* The cast here works around a difference between Python 2.4 and 833 Python 2.5. */ 834 (CHARBUFFERPROC_NAME) get_char_buffer 835 }; 836 837 static PyTypeObject membuf_object_type = { 838 PyObject_HEAD_INIT (NULL) 839 0, /*ob_size*/ 840 "gdb.Membuf", /*tp_name*/ 841 sizeof (membuf_object), /*tp_basicsize*/ 842 0, /*tp_itemsize*/ 843 mbpy_dealloc, /*tp_dealloc*/ 844 0, /*tp_print*/ 845 0, /*tp_getattr*/ 846 0, /*tp_setattr*/ 847 0, /*tp_compare*/ 848 0, /*tp_repr*/ 849 0, /*tp_as_number*/ 850 0, /*tp_as_sequence*/ 851 0, /*tp_as_mapping*/ 852 0, /*tp_hash */ 853 0, /*tp_call*/ 854 mbpy_str, /*tp_str*/ 855 0, /*tp_getattro*/ 856 0, /*tp_setattro*/ 857 &buffer_procs, /*tp_as_buffer*/ 858 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 859 "GDB memory buffer object", /*tp_doc*/ 860 0, /* tp_traverse */ 861 0, /* tp_clear */ 862 0, /* tp_richcompare */ 863 0, /* tp_weaklistoffset */ 864 0, /* tp_iter */ 865 0, /* tp_iternext */ 866 0, /* tp_methods */ 867 0, /* tp_members */ 868 0, /* tp_getset */ 869 0, /* tp_base */ 870 0, /* tp_dict */ 871 0, /* tp_descr_get */ 872 0, /* tp_descr_set */ 873 0, /* tp_dictoffset */ 874 0, /* tp_init */ 875 0, /* tp_alloc */ 876 }; 877