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