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