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