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